File: /home/joenio/src/dissertacao-ufba-2016/dataset/PAPERS/inputtracer/valgrind-inputtracer/perf/tinycc.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #define _GNU_SOURCE
21
22
23
24
25
26 #define CONFIG_TCCDIR "tinycc-extras"
27 #define GCC_MAJOR 3
28 #define HOST_I386 1
29 #define TCC_VERSION "0.9.23"
30
31
32
33
34
35
36
37
38
39
40 #include <assert.h>
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <stdarg.h>
44 #include <string.h>
45 #include <errno.h>
46 #include <math.h>
47 #include <unistd.h>
48 #include <signal.h>
49 #include <fcntl.h>
50 #include <setjmp.h>
51 #include <time.h>
52 #ifdef WIN32
53 #include <sys/timeb.h>
54 #endif
55 #ifndef WIN32
56 #include <sys/time.h>
57 #include <sys/ucontext.h>
58 #endif
59
60
61
62
63
64
65 char* dummy_char_star;
66 size_t dummy_size_t;
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91 #ifndef _ELF_H
92 #define _ELF_H 1
93
94 #ifndef WIN32
95 #include <inttypes.h>
96 #else
97 #ifndef __int8_t_defined
98 #define __int8_t_defined
99 typedef signed char int8_t;
100 typedef short int int16_t;
101 typedef int int32_t;
102 typedef long long int int64_t;
103 #endif
104
105 typedef unsigned char uint8_t;
106 typedef unsigned short int uint16_t;
107 typedef unsigned int uint32_t;
108 typedef unsigned long long int uint64_t;
109 #endif
110
111
112
113
114 typedef uint16_t Elf32_Half;
115 typedef uint16_t Elf64_Half;
116
117
118 typedef uint32_t Elf32_Word;
119 typedef int32_t Elf32_Sword;
120 typedef uint32_t Elf64_Word;
121 typedef int32_t Elf64_Sword;
122
123
124 typedef uint64_t Elf32_Xword;
125 typedef int64_t Elf32_Sxword;
126 typedef uint64_t Elf64_Xword;
127 typedef int64_t Elf64_Sxword;
128
129
130 typedef uint32_t Elf32_Addr;
131 typedef uint64_t Elf64_Addr;
132
133
134 typedef uint32_t Elf32_Off;
135 typedef uint64_t Elf64_Off;
136
137
138 typedef uint16_t Elf32_Section;
139 typedef uint16_t Elf64_Section;
140
141
142 typedef uint32_t Elf32_Symndx;
143 typedef uint64_t Elf64_Symndx;
144
145
146
147
148 #define EI_NIDENT (16)
149
150 typedef struct
151 {
152 unsigned char e_ident[EI_NIDENT];
153 ;
154 ;
155 ;
156 ;
157 ;
158 ;
159 ;
160 ;
161 ;
162 ;
163 ;
164 ;
165 ;
166 } Elf32_Ehdr;
167
168 typedef struct
169 {
170 unsigned char e_ident[EI_NIDENT];
171 ;
172 ;
173 ;
174 ;
175 ;
176 ;
177 ;
178 ;
179 ;
180 ;
181 ;
182 ;
183 ;
184 } Elf64_Ehdr;
185
186
187
188
189
190 #define EI_MAG0 0
191 #define ELFMAG0 0x7f
192
193 #define EI_MAG1 1
194 #define ELFMAG1 'E'
195
196 #define EI_MAG2 2
197 #define ELFMAG2 'L'
198
199 #define EI_MAG3 3
200 #define ELFMAG3 'F'
201
202
203 #define ELFMAG "\177ELF"
204 #define SELFMAG 4
205
206 #define EI_CLASS 4
207 #define ELFCLASSNONE 0
208 #define ELFCLASS32 1
209 #define ELFCLASS64 2
210 #define ELFCLASSNUM 3
211
212 #define EI_DATA 5
213 #define ELFDATANONE 0
214 #define ELFDATA2LSB 1
215 #define ELFDATA2MSB 2
216 #define ELFDATANUM 3
217
218 #define EI_VERSION 6
219
220
221 #define EI_OSABI 7
222 #define ELFOSABI_SYSV 0
223 #define ELFOSABI_HPUX 1
224 #define ELFOSABI_FREEBSD 9
225 #define ELFOSABI_ARM 97
226 #define ELFOSABI_STANDALONE 255
227
228 #define EI_ABIVERSION 8
229
230 #define EI_PAD 9
231
232
233
234 #define ET_NONE 0
235 #define ET_REL 1
236 #define ET_EXEC 2
237 #define ET_DYN 3
238 #define ET_CORE 4
239 #define ET_NUM 5
240 #define ET_LOPROC 0xff00
241 #define ET_HIPROC 0xffff
242
243
244
245 #define EM_NONE 0
246 #define EM_M32 1
247 #define EM_SPARC 2
248 #define EM_386 3
249 #define EM_68K 4
250 #define EM_88K 5
251 #define EM_486 6
252 #define EM_860 7
253 #define EM_MIPS 8
254 #define EM_S370 9
255 #define EM_MIPS_RS4_BE 10
256 #define EM_RS6000 11
257
258 #define EM_PARISC 15
259 #define EM_nCUBE 16
260 #define EM_VPP500 17
261 #define EM_SPARC32PLUS 18
262 #define EM_960 19
263 #define EM_PPC 20
264
265 #define EM_V800 36
266 #define EM_FR20 37
267 #define EM_RH32 38
268 #define EM_MMA 39
269 #define EM_ARM 40
270 #define EM_FAKE_ALPHA 41
271 #define EM_SH 42
272 #define EM_SPARCV9 43
273 #define EM_TRICORE 44
274 #define EM_ARC 45
275 #define EM_H8_300 46
276 #define EM_H8_300H 47
277 #define EM_H8S 48
278 #define EM_H8_500 49
279 #define EM_IA_64 50
280 #define EM_MIPS_X 51
281 #define EM_COLDFIRE 52
282 #define EM_68HC12 53
283 #define EM_NUM 54
284
285
286
287
288
289 #define EM_ALPHA 0x9026
290 #define EM_C60 0x9c60
291
292
293
294 #define EV_NONE 0
295 #define EV_CURRENT 1
296 #define EV_NUM 2
297
298
299
300 typedef struct
301 {
302 Elf32_Word sh_name;
303 ;
304 ;
305 ;
306 ;
307 ;
308 ;
309 ;
310 ;
311 ;
312 } Elf32_Shdr;
313
314 typedef struct
315 {
316 Elf64_Word sh_name;
317 ;
318 ;
319 ;
320 ;
321 ;
322 ;
323 ;
324 ;
325 ;
326 } Elf64_Shdr;
327
328
329
330 #define SHN_UNDEF 0
331 #define SHN_LORESERVE 0xff00
332 #define SHN_LOPROC 0xff00
333 #define SHN_HIPROC 0xff1f
334 #define SHN_ABS 0xfff1
335 #define SHN_COMMON 0xfff2
336 #define SHN_HIRESERVE 0xffff
337
338
339
340 #define SHT_NULL 0
341 #define SHT_PROGBITS 1
342 #define SHT_SYMTAB 2
343 #define SHT_STRTAB 3
344 #define SHT_RELA 4
345 #define SHT_HASH 5
346 #define SHT_DYNAMIC 6
347 #define SHT_NOTE 7
348 #define SHT_NOBITS 8
349 #define SHT_REL 9
350 #define SHT_SHLIB 10
351 #define SHT_DYNSYM 11
352 #define SHT_NUM 12
353 #define SHT_LOOS 0x60000000
354 #define SHT_LOSUNW 0x6ffffffb
355 #define SHT_SUNW_COMDAT 0x6ffffffb
356 #define SHT_SUNW_syminfo 0x6ffffffc
357 #define SHT_GNU_verdef 0x6ffffffd
358 #define SHT_GNU_verneed 0x6ffffffe
359 #define SHT_GNU_versym 0x6fffffff
360 #define SHT_HISUNW 0x6fffffff
361 #define SHT_HIOS 0x6fffffff
362 #define SHT_LOPROC 0x70000000
363 #define SHT_HIPROC 0x7fffffff
364 #define SHT_LOUSER 0x80000000
365 #define SHT_HIUSER 0x8fffffff
366
367
368
369 #define SHF_WRITE (1 << 0)
370 #define SHF_ALLOC (1 << 1)
371 #define SHF_EXECINSTR (1 << 2)
372 #define SHF_MASKPROC 0xf0000000
373
374
375
376 typedef struct
377 {
378 Elf32_Word st_name;
379 ;
380 ;
381 unsigned char st_info;
382 unsigned char st_other;
383 ;
384 } Elf32_Sym;
385
386 typedef struct
387 {
388 Elf64_Word st_name;
389 unsigned char st_info;
390 unsigned char st_other;
391 ;
392 ;
393 ;
394 } Elf64_Sym;
395
396
397
398
399 typedef struct
400 {
401 Elf32_Half si_boundto;
402 ;
403 } Elf32_Syminfo;
404
405 typedef struct
406 {
407 Elf64_Half si_boundto;
408 ;
409 } Elf64_Syminfo;
410
411
412 #define SYMINFO_BT_SELF 0xffff
413 #define SYMINFO_BT_PARENT 0xfffe
414 #define SYMINFO_BT_LOWRESERVE 0xff00
415
416
417 #define SYMINFO_FLG_DIRECT 0x0001
418 #define SYMINFO_FLG_PASSTHRU 0x0002
419 #define SYMINFO_FLG_COPY 0x0004
420 #define SYMINFO_FLG_LAZYLOAD 0x0008
421
422
423 #define SYMINFO_NONE 0
424 #define SYMINFO_CURRENT 1
425 #define SYMINFO_NUM 2
426
427
428
429
430 #define SHN_UNDEF 0
431
432
433
434 #define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4)
435 #define ELF32_ST_TYPE(val) ((val) & 0xf)
436 #define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
437
438
439 #define ELF64_ST_BIND(val) ELF32_ST_BIND (val)
440 #define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val)
441 #define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type))
442
443
444
445 #define STB_LOCAL 0
446 #define STB_GLOBAL 1
447 #define STB_WEAK 2
448 #define STB_NUM 3
449 #define STB_LOOS 10
450 #define STB_HIOS 12
451 #define STB_LOPROC 13
452 #define STB_HIPROC 15
453
454
455
456 #define STT_NOTYPE 0
457 #define STT_OBJECT 1
458 #define STT_FUNC 2
459 #define STT_SECTION 3
460 #define STT_FILE 4
461 #define STT_NUM 5
462 #define STT_LOOS 11
463 #define STT_HIOS 12
464 #define STT_LOPROC 13
465 #define STT_HIPROC 15
466
467
468
469
470
471
472 #define STN_UNDEF 0
473
474
475
476
477 #define ELF32_ST_VISIBILITY(o) ((o) & 0x03)
478
479
480 #define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o)
481
482
483 #define STV_DEFAULT 0
484 #define STV_INTERNAL 1
485 #define STV_HIDDEN 2
486 #define STV_PROTECTED 3
487
488
489
490
491 typedef struct
492 {
493 Elf32_Addr r_offset;
494 ;
495 } Elf32_Rel;
496
497
498
499
500
501
502 typedef struct
503 {
504 Elf64_Addr r_offset;
505 ;
506 } Elf64_Rel;
507
508
509
510 typedef struct
511 {
512 Elf32_Addr r_offset;
513 ;
514 ;
515 } Elf32_Rela;
516
517 typedef struct
518 {
519 Elf64_Addr r_offset;
520 ;
521 ;
522 } Elf64_Rela;
523
524
525
526 #define ELF32_R_SYM(val) ((val) >> 8)
527 #define ELF32_R_TYPE(val) ((val) & 0xff)
528 #define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff))
529
530 #define ELF64_R_SYM(i) ((i) >> 32)
531 #define ELF64_R_TYPE(i) ((i) & 0xffffffff)
532 #define ELF64_R_INFO(sym,type) (((sym) << 32) + (type))
533
534
535
536 typedef struct
537 {
538 Elf32_Word p_type;
539 ;
540 ;
541 ;
542 ;
543 ;
544 ;
545 ;
546 } Elf32_Phdr;
547
548 typedef struct
549 {
550 Elf64_Word p_type;
551 ;
552 ;
553 ;
554 ;
555 ;
556 ;
557 ;
558 } Elf64_Phdr;
559
560
561
562 #define PT_NULL 0
563 #define PT_LOAD 1
564 #define PT_DYNAMIC 2
565 #define PT_INTERP 3
566 #define PT_NOTE 4
567 #define PT_SHLIB 5
568 #define PT_PHDR 6
569 #define PT_NUM 7
570 #define PT_LOOS 0x60000000
571 #define PT_HIOS 0x6fffffff
572 #define PT_LOPROC 0x70000000
573 #define PT_HIPROC 0x7fffffff
574
575
576
577 #define PF_X (1 << 0)
578 #define PF_W (1 << 1)
579 #define PF_R (1 << 2)
580 #define PF_MASKPROC 0xf0000000
581
582
583
584 #define NT_PRSTATUS 1
585 #define NT_FPREGSET 2
586 #define NT_PRPSINFO 3
587 #define NT_PRXREG 4
588 #define NT_PLATFORM 5
589 #define NT_AUXV 6
590 #define NT_GWINDOWS 7
591 #define NT_PSTATUS 10
592 #define NT_PSINFO 13
593 #define NT_PRCRED 14
594 #define NT_UTSNAME 15
595 #define NT_LWPSTATUS 16
596 #define NT_LWPSINFO 17
597
598
599
600 #define NT_VERSION 1
601
602
603
604
605 typedef struct
606 {
607 Elf32_Sword d_tag;
608 union
609 {
610 Elf32_Word d_val;
611 ;
612 } d_un;
613 } Elf32_Dyn;
614
615 typedef struct
616 {
617 Elf64_Sxword d_tag;
618 union
619 {
620 Elf64_Xword d_val;
621 ;
622 } d_un;
623 } Elf64_Dyn;
624
625
626
627 #define DT_NULL 0
628 #define DT_NEEDED 1
629 #define DT_PLTRELSZ 2
630 #define DT_PLTGOT 3
631 #define DT_HASH 4
632 #define DT_STRTAB 5
633 #define DT_SYMTAB 6
634 #define DT_RELA 7
635 #define DT_RELASZ 8
636 #define DT_RELAENT 9
637 #define DT_STRSZ 10
638 #define DT_SYMENT 11
639 #define DT_INIT 12
640 #define DT_FINI 13
641 #define DT_SONAME 14
642 #define DT_RPATH 15
643 #define DT_SYMBOLIC 16
644 #define DT_REL 17
645 #define DT_RELSZ 18
646 #define DT_RELENT 19
647 #define DT_PLTREL 20
648 #define DT_DEBUG 21
649 #define DT_TEXTREL 22
650 #define DT_JMPREL 23
651 #define DT_BIND_NOW 24
652 #define DT_INIT_ARRAY 25
653 #define DT_FINI_ARRAY 26
654 #define DT_INIT_ARRAYSZ 27
655 #define DT_FINI_ARRAYSZ 28
656 #define DT_NUM 29
657 #define DT_LOOS 0x60000000
658 #define DT_HIOS 0x6fffffff
659 #define DT_LOPROC 0x70000000
660 #define DT_HIPROC 0x7fffffff
661 #define DT_PROCNUM DT_MIPS_NUM
662
663
664
665
666 #define DT_VALRNGLO 0x6ffffd00
667 #define DT_POSFLAG_1 0x6ffffdfd
668
669 #define DT_SYMINSZ 0x6ffffdfe
670 #define DT_SYMINENT 0x6ffffdff
671 #define DT_VALRNGHI 0x6ffffdff
672
673
674
675
676
677
678 #define DT_ADDRRNGLO 0x6ffffe00
679 #define DT_SYMINFO 0x6ffffeff
680 #define DT_ADDRRNGHI 0x6ffffeff
681
682
683
684 #define DT_VERSYM 0x6ffffff0
685
686
687 #define DT_FLAGS_1 0x6ffffffb
688 #define DT_VERDEF 0x6ffffffc
689
690 #define DT_VERDEFNUM 0x6ffffffd
691 #define DT_VERNEED 0x6ffffffe
692
693 #define DT_VERNEEDNUM 0x6fffffff
694 #define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag))
695 #define DT_VERSIONTAGNUM 16
696
697
698
699 #define DT_AUXILIARY 0x7ffffffd
700 #define DT_FILTER 0x7fffffff
701 #define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1)
702 #define DT_EXTRANUM 3
703
704
705
706 #define DF_1_NOW 0x00000001
707 #define DF_1_GLOBAL 0x00000002
708 #define DF_1_GROUP 0x00000004
709 #define DF_1_NODELETE 0x00000008
710 #define DF_1_LOADFLTR 0x00000010
711 #define DF_1_INITFIRST 0x00000020
712 #define DF_1_NOOPEN 0x00000040
713
714
715
716 typedef struct
717 {
718 Elf32_Half vd_version;
719 ;
720 ;
721 ;
722 ;
723 ;
724 ;
725
726 } Elf32_Verdef;
727
728 typedef struct
729 {
730 Elf64_Half vd_version;
731 ;
732 ;
733 ;
734 ;
735 ;
736 ;
737
738 } Elf64_Verdef;
739
740
741
742 #define VER_DEF_NONE 0
743 #define VER_DEF_CURRENT 1
744 #define VER_DEF_NUM 2
745
746
747 #define VER_FLG_BASE 0x1
748 #define VER_FLG_WEAK 0x2
749
750
751
752 typedef struct
753 {
754 Elf32_Word vda_name;
755 ;
756
757 } Elf32_Verdaux;
758
759 typedef struct
760 {
761 Elf64_Word vda_name;
762 ;
763
764 } Elf64_Verdaux;
765
766
767
768
769 typedef struct
770 {
771 Elf32_Half vn_version;
772 ;
773 ;
774
775 ;
776 ;
777
778 } Elf32_Verneed;
779
780 typedef struct
781 {
782 Elf64_Half vn_version;
783 ;
784 ;
785
786 ;
787 ;
788
789 } Elf64_Verneed;
790
791
792
793 #define VER_NEED_NONE 0
794 #define VER_NEED_CURRENT 1
795 #define VER_NEED_NUM 2
796
797
798
799 typedef struct
800 {
801 Elf32_Word vna_hash;
802 ;
803 ;
804 ;
805 ;
806
807 } Elf32_Vernaux;
808
809 typedef struct
810 {
811 Elf64_Word vna_hash;
812 ;
813 ;
814 ;
815 ;
816
817 } Elf64_Vernaux;
818
819
820
821 #define VER_FLG_WEAK 0x2
822
823
824
825
826
827
828
829
830
831
832
833 typedef struct
834 {
835 int a_type;
836 union
837 {
838 long int a_val;
839 void *a_ptr;
840 void (*a_fcn) (void);
841 } a_un;
842 } Elf32_auxv_t;
843
844 typedef struct
845 {
846 long int a_type;
847 union
848 {
849 long int a_val;
850 void *a_ptr;
851 void (*a_fcn) (void);
852 } a_un;
853 } Elf64_auxv_t;
854
855
856
857 #define AT_NULL 0
858 #define AT_IGNORE 1
859 #define AT_EXECFD 2
860 #define AT_PHDR 3
861 #define AT_PHENT 4
862 #define AT_PHNUM 5
863 #define AT_PAGESZ 6
864 #define AT_BASE 7
865 #define AT_FLAGS 8
866 #define AT_ENTRY 9
867 #define AT_NOTELF 10
868 #define AT_UID 11
869 #define AT_EUID 12
870 #define AT_GID 13
871 #define AT_EGID 14
872
873
874 #define AT_PLATFORM 15
875 #define AT_HWCAP 16
876
877
878
879
880 #define AT_FPUCW 17
881
882
883
884
885
886 typedef struct
887 {
888 Elf32_Word n_namesz;
889 ;
890 ;
891 } Elf32_Nhdr;
892
893 typedef struct
894 {
895 Elf64_Word n_namesz;
896 ;
897 ;
898 } Elf64_Nhdr;
899
900
901
902
903 #define ELF_NOTE_SOLARIS "SUNW Solaris"
904
905
906 #define ELF_NOTE_GNU "GNU"
907
908
909
910
911
912 #define ELF_NOTE_PAGESIZE_HINT 1
913
914
915
916
917
918
919
920
921
922
923 #define ELF_NOTE_ABI 1
924
925
926
927 #define ELF_NOTE_OS_LINUX 0
928 #define ELF_NOTE_OS_GNU 1
929 #define ELF_NOTE_OS_SOLARIS2 2
930
931
932
933
934
935
936 #define R_68K_NONE 0
937 #define R_68K_32 1
938 #define R_68K_16 2
939 #define R_68K_8 3
940 #define R_68K_PC32 4
941 #define R_68K_PC16 5
942 #define R_68K_PC8 6
943 #define R_68K_GOT32 7
944 #define R_68K_GOT16 8
945 #define R_68K_GOT8 9
946 #define R_68K_GOT32O 10
947 #define R_68K_GOT16O 11
948 #define R_68K_GOT8O 12
949 #define R_68K_PLT32 13
950 #define R_68K_PLT16 14
951 #define R_68K_PLT8 15
952 #define R_68K_PLT32O 16
953 #define R_68K_PLT16O 17
954 #define R_68K_PLT8O 18
955 #define R_68K_COPY 19
956 #define R_68K_GLOB_DAT 20
957 #define R_68K_JMP_SLOT 21
958 #define R_68K_RELATIVE 22
959
960 #define R_68K_NUM 23
961
962
963
964
965
966 #define R_386_NONE 0
967 #define R_386_32 1
968 #define R_386_PC32 2
969 #define R_386_GOT32 3
970 #define R_386_PLT32 4
971 #define R_386_COPY 5
972 #define R_386_GLOB_DAT 6
973 #define R_386_JMP_SLOT 7
974 #define R_386_RELATIVE 8
975 #define R_386_GOTOFF 9
976 #define R_386_GOTPC 10
977
978 #define R_386_NUM 11
979
980
981
982
983
984 #define EF_SPARCV9_MM 3
985 #define EF_SPARCV9_TSO 0
986 #define EF_SPARCV9_PSO 1
987 #define EF_SPARCV9_RMO 2
988 #define EF_SPARC_EXT_MASK 0xFFFF00
989 #define EF_SPARC_SUN_US1 0x000200
990 #define EF_SPARC_HAL_R1 0x000400
991
992
993
994 #define R_SPARC_NONE 0
995 #define R_SPARC_8 1
996 #define R_SPARC_16 2
997 #define R_SPARC_32 3
998 #define R_SPARC_DISP8 4
999 #define R_SPARC_DISP16 5
1000 #define R_SPARC_DISP32 6
1001 #define R_SPARC_WDISP30 7
1002 #define R_SPARC_WDISP22 8
1003 #define R_SPARC_HI22 9
1004 #define R_SPARC_22 10
1005 #define R_SPARC_13 11
1006 #define R_SPARC_LO10 12
1007 #define R_SPARC_GOT10 13
1008 #define R_SPARC_GOT13 14
1009 #define R_SPARC_GOT22 15
1010 #define R_SPARC_PC10 16
1011 #define R_SPARC_PC22 17
1012 #define R_SPARC_WPLT30 18
1013 #define R_SPARC_COPY 19
1014 #define R_SPARC_GLOB_DAT 20
1015 #define R_SPARC_JMP_SLOT 21
1016 #define R_SPARC_RELATIVE 22
1017 #define R_SPARC_UA32 23
1018
1019
1020
1021 #define R_SPARC_PLT32 24
1022 #define R_SPARC_HIPLT22 25
1023 #define R_SPARC_LOPLT10 26
1024 #define R_SPARC_PCPLT32 27
1025 #define R_SPARC_PCPLT22 28
1026 #define R_SPARC_PCPLT10 29
1027 #define R_SPARC_10 30
1028 #define R_SPARC_11 31
1029 #define R_SPARC_64 32
1030 #define R_SPARC_OLO10 33
1031 #define R_SPARC_HH22 34
1032 #define R_SPARC_HM10 35
1033 #define R_SPARC_LM22 36
1034 #define R_SPARC_PC_HH22 37
1035 #define R_SPARC_PC_HM10 38
1036 #define R_SPARC_PC_LM22 39
1037 #define R_SPARC_WDISP16 40
1038 #define R_SPARC_WDISP19 41
1039 #define R_SPARC_7 43
1040 #define R_SPARC_5 44
1041 #define R_SPARC_6 45
1042 #define R_SPARC_DISP64 46
1043 #define R_SPARC_PLT64 47
1044 #define R_SPARC_HIX22 48
1045 #define R_SPARC_LOX10 49
1046 #define R_SPARC_H44 50
1047 #define R_SPARC_M44 51
1048 #define R_SPARC_L44 52
1049 #define R_SPARC_REGISTER 53
1050 #define R_SPARC_UA64 54
1051 #define R_SPARC_UA16 55
1052
1053 #define R_SPARC_NUM 56
1054
1055
1056
1057 #define DT_SPARC_REGISTER 0x70000001
1058 #define DT_SPARC_NUM 2
1059
1060
1061
1062 #define HWCAP_SPARC_FLUSH 1
1063 #define HWCAP_SPARC_STBAR 2
1064 #define HWCAP_SPARC_SWAP 4
1065 #define HWCAP_SPARC_MULDIV 8
1066 #define HWCAP_SPARC_V9 16
1067
1068
1069
1070
1071
1072 #define EF_MIPS_NOREORDER 1
1073 #define EF_MIPS_PIC 2
1074 #define EF_MIPS_CPIC 4
1075 #define EF_MIPS_XGOT 8
1076 #define EF_MIPS_64BIT_WHIRL 16
1077 #define EF_MIPS_ABI2 32
1078 #define EF_MIPS_ABI_ON32 64
1079 #define EF_MIPS_ARCH 0xf0000000
1080
1081
1082
1083 #define EF_MIPS_ARCH_1 0x00000000
1084 #define EF_MIPS_ARCH_2 0x10000000
1085 #define EF_MIPS_ARCH_3 0x20000000
1086 #define EF_MIPS_ARCH_4 0x30000000
1087 #define EF_MIPS_ARCH_5 0x40000000
1088
1089
1090
1091 #define E_MIPS_ARCH_1 0x00000000
1092 #define E_MIPS_ARCH_2 0x10000000
1093 #define E_MIPS_ARCH_3 0x20000000
1094 #define E_MIPS_ARCH_4 0x30000000
1095 #define E_MIPS_ARCH_5 0x40000000
1096
1097
1098
1099 #define SHN_MIPS_ACOMMON 0xff00
1100 #define SHN_MIPS_TEXT 0xff01
1101 #define SHN_MIPS_DATA 0xff02
1102 #define SHN_MIPS_SCOMMON 0xff03
1103 #define SHN_MIPS_SUNDEFINED 0xff04
1104
1105
1106
1107 #define SHT_MIPS_LIBLIST 0x70000000
1108 #define SHT_MIPS_MSYM 0x70000001
1109 #define SHT_MIPS_CONFLICT 0x70000002
1110 #define SHT_MIPS_GPTAB 0x70000003
1111 #define SHT_MIPS_UCODE 0x70000004
1112 #define SHT_MIPS_DEBUG 0x70000005
1113 #define SHT_MIPS_REGINFO 0x70000006
1114 #define SHT_MIPS_PACKAGE 0x70000007
1115 #define SHT_MIPS_PACKSYM 0x70000008
1116 #define SHT_MIPS_RELD 0x70000009
1117 #define SHT_MIPS_IFACE 0x7000000b
1118 #define SHT_MIPS_CONTENT 0x7000000c
1119 #define SHT_MIPS_OPTIONS 0x7000000d
1120 #define SHT_MIPS_SHDR 0x70000010
1121 #define SHT_MIPS_FDESC 0x70000011
1122 #define SHT_MIPS_EXTSYM 0x70000012
1123 #define SHT_MIPS_DENSE 0x70000013
1124 #define SHT_MIPS_PDESC 0x70000014
1125 #define SHT_MIPS_LOCSYM 0x70000015
1126 #define SHT_MIPS_AUXSYM 0x70000016
1127 #define SHT_MIPS_OPTSYM 0x70000017
1128 #define SHT_MIPS_LOCSTR 0x70000018
1129 #define SHT_MIPS_LINE 0x70000019
1130 #define SHT_MIPS_RFDESC 0x7000001a
1131 #define SHT_MIPS_DELTASYM 0x7000001b
1132 #define SHT_MIPS_DELTAINST 0x7000001c
1133 #define SHT_MIPS_DELTACLASS 0x7000001d
1134 #define SHT_MIPS_DWARF 0x7000001e
1135 #define SHT_MIPS_DELTADECL 0x7000001f
1136 #define SHT_MIPS_SYMBOL_LIB 0x70000020
1137 #define SHT_MIPS_EVENTS 0x70000021
1138 #define SHT_MIPS_TRANSLATE 0x70000022
1139 #define SHT_MIPS_PIXIE 0x70000023
1140 #define SHT_MIPS_XLATE 0x70000024
1141 #define SHT_MIPS_XLATE_DEBUG 0x70000025
1142 #define SHT_MIPS_WHIRL 0x70000026
1143 #define SHT_MIPS_EH_REGION 0x70000027
1144 #define SHT_MIPS_XLATE_OLD 0x70000028
1145 #define SHT_MIPS_PDR_EXCEPTION 0x70000029
1146
1147
1148
1149 #define SHF_MIPS_GPREL 0x10000000
1150 #define SHF_MIPS_MERGE 0x20000000
1151 #define SHF_MIPS_ADDR 0x40000000
1152 #define SHF_MIPS_STRINGS 0x80000000
1153 #define SHF_MIPS_NOSTRIP 0x08000000
1154 #define SHF_MIPS_LOCAL 0x04000000
1155 #define SHF_MIPS_NAMES 0x02000000
1156 #define SHF_MIPS_NODUPE 0x01000000
1157
1158
1159
1160
1161
1162 #define STO_MIPS_DEFAULT 0x0
1163 #define STO_MIPS_INTERNAL 0x1
1164 #define STO_MIPS_HIDDEN 0x2
1165 #define STO_MIPS_PROTECTED 0x3
1166 #define STO_MIPS_SC_ALIGN_UNUSED 0xff
1167
1168
1169 #define STB_MIPS_SPLIT_COMMON 13
1170
1171
1172
1173 typedef union
1174 {
1175 struct
1176 {
1177 Elf32_Word gt_current_g_value;
1178 ;
1179 } gt_header;
1180 struct
1181 {
1182 Elf32_Word gt_g_value;
1183 ;
1184 } gt_entry;
1185 } Elf32_gptab;
1186
1187
1188
1189 typedef struct
1190 {
1191 Elf32_Word ri_gprmask;
1192 [4];
1193 ;
1194 } Elf32_RegInfo;
1195
1196
1197
1198 typedef struct
1199 {
1200 unsigned char kind;
1201
1202 unsigned char size;
1203 ;
1204
1205 ;
1206 } Elf_Options;
1207
1208
1209
1210 #define ODK_NULL 0
1211 #define ODK_REGINFO 1
1212 #define ODK_EXCEPTIONS 2
1213 #define ODK_PAD 3
1214 #define ODK_HWPATCH 4
1215 #define ODK_FILL 5
1216 #define ODK_TAGS 6
1217 #define ODK_HWAND 7
1218 #define ODK_HWOR 8
1219
1220
1221
1222 #define OEX_FPU_MIN 0x1f
1223 #define OEX_FPU_MAX 0x1f00
1224 #define OEX_PAGE0 0x10000
1225 #define OEX_SMM 0x20000
1226 #define OEX_FPDBUG 0x40000
1227 #define OEX_PRECISEFP OEX_FPDBUG
1228 #define OEX_DISMISS 0x80000
1229
1230 #define OEX_FPU_INVAL 0x10
1231 #define OEX_FPU_DIV0 0x08
1232 #define OEX_FPU_OFLO 0x04
1233 #define OEX_FPU_UFLO 0x02
1234 #define OEX_FPU_INEX 0x01
1235
1236
1237
1238 #define OHW_R4KEOP 0x1
1239 #define OHW_R8KPFETCH 0x2
1240 #define OHW_R5KEOP 0x4
1241 #define OHW_R5KCVTL 0x8
1242
1243 #define OPAD_PREFIX 0x1
1244 #define OPAD_POSTFIX 0x2
1245 #define OPAD_SYMBOL 0x4
1246
1247
1248
1249 typedef struct
1250 {
1251 Elf32_Word hwp_flags1;
1252 ;
1253 } Elf_Options_Hw;
1254
1255
1256
1257 #define OHWA0_R4KEOP_CHECKED 0x00000001
1258 #define OHWA1_R4KEOP_CLEAN 0x00000002
1259
1260
1261
1262 #define R_MIPS_NONE 0
1263 #define R_MIPS_16 1
1264 #define R_MIPS_32 2
1265 #define R_MIPS_REL32 3
1266 #define R_MIPS_26 4
1267 #define R_MIPS_HI16 5
1268 #define R_MIPS_LO16 6
1269 #define R_MIPS_GPREL16 7
1270 #define R_MIPS_LITERAL 8
1271 #define R_MIPS_GOT16 9
1272 #define R_MIPS_PC16 10
1273 #define R_MIPS_CALL16 11
1274 #define R_MIPS_GPREL32 12
1275
1276 #define R_MIPS_SHIFT5 16
1277 #define R_MIPS_SHIFT6 17
1278 #define R_MIPS_64 18
1279 #define R_MIPS_GOT_DISP 19
1280 #define R_MIPS_GOT_PAGE 20
1281 #define R_MIPS_GOT_OFST 21
1282 #define R_MIPS_GOT_HI16 22
1283 #define R_MIPS_GOT_LO16 23
1284 #define R_MIPS_SUB 24
1285 #define R_MIPS_INSERT_A 25
1286 #define R_MIPS_INSERT_B 26
1287 #define R_MIPS_DELETE 27
1288 #define R_MIPS_HIGHER 28
1289 #define R_MIPS_HIGHEST 29
1290 #define R_MIPS_CALL_HI16 30
1291 #define R_MIPS_CALL_LO16 31
1292 #define R_MIPS_SCN_DISP 32
1293 #define R_MIPS_REL16 33
1294 #define R_MIPS_ADD_IMMEDIATE 34
1295 #define R_MIPS_PJUMP 35
1296 #define R_MIPS_RELGOT 36
1297 #define R_MIPS_JALR 37
1298
1299 #define R_MIPS_NUM 38
1300
1301
1302
1303 #define PT_MIPS_REGINFO 0x70000000
1304 #define PT_MIPS_RTPROC 0x70000001
1305 #define PT_MIPS_OPTIONS 0x70000002
1306
1307
1308
1309 #define PF_MIPS_LOCAL 0x10000000
1310
1311
1312
1313 #define DT_MIPS_RLD_VERSION 0x70000001
1314 #define DT_MIPS_TIME_STAMP 0x70000002
1315 #define DT_MIPS_ICHECKSUM 0x70000003
1316 #define DT_MIPS_IVERSION 0x70000004
1317 #define DT_MIPS_FLAGS 0x70000005
1318 #define DT_MIPS_BASE_ADDRESS 0x70000006
1319 #define DT_MIPS_MSYM 0x70000007
1320 #define DT_MIPS_CONFLICT 0x70000008
1321 #define DT_MIPS_LIBLIST 0x70000009
1322 #define DT_MIPS_LOCAL_GOTNO 0x7000000a
1323 #define DT_MIPS_CONFLICTNO 0x7000000b
1324 #define DT_MIPS_LIBLISTNO 0x70000010
1325 #define DT_MIPS_SYMTABNO 0x70000011
1326 #define DT_MIPS_UNREFEXTNO 0x70000012
1327 #define DT_MIPS_GOTSYM 0x70000013
1328 #define DT_MIPS_HIPAGENO 0x70000014
1329 #define DT_MIPS_RLD_MAP 0x70000016
1330 #define DT_MIPS_DELTA_CLASS 0x70000017
1331 #define DT_MIPS_DELTA_CLASS_NO 0x70000018
1332
1333 #define DT_MIPS_DELTA_INSTANCE 0x70000019
1334 #define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a
1335
1336 #define DT_MIPS_DELTA_RELOC 0x7000001b
1337 #define DT_MIPS_DELTA_RELOC_NO 0x7000001c
1338
1339 #define DT_MIPS_DELTA_SYM 0x7000001d
1340
1341 #define DT_MIPS_DELTA_SYM_NO 0x7000001e
1342
1343 #define DT_MIPS_DELTA_CLASSSYM 0x70000020
1344
1345 #define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021
1346
1347 #define DT_MIPS_CXX_FLAGS 0x70000022
1348 #define DT_MIPS_PIXIE_INIT 0x70000023
1349 #define DT_MIPS_SYMBOL_LIB 0x70000024
1350 #define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
1351 #define DT_MIPS_LOCAL_GOTIDX 0x70000026
1352 #define DT_MIPS_HIDDEN_GOTIDX 0x70000027
1353 #define DT_MIPS_PROTECTED_GOTIDX 0x70000028
1354 #define DT_MIPS_OPTIONS 0x70000029
1355 #define DT_MIPS_INTERFACE 0x7000002a
1356 #define DT_MIPS_DYNSTR_ALIGN 0x7000002b
1357 #define DT_MIPS_INTERFACE_SIZE 0x7000002c
1358 #define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d
1359
1360 #define DT_MIPS_PERF_SUFFIX 0x7000002e
1361
1362 #define DT_MIPS_COMPACT_SIZE 0x7000002f
1363 #define DT_MIPS_GP_VALUE 0x70000030
1364 #define DT_MIPS_AUX_DYNAMIC 0x70000031
1365 #define DT_MIPS_NUM 0x32
1366
1367
1368
1369 #define RHF_NONE 0
1370 #define RHF_QUICKSTART (1 << 0)
1371 #define RHF_NOTPOT (1 << 1)
1372 #define RHF_NO_LIBRARY_REPLACEMENT (1 << 2)
1373 #define RHF_NO_MOVE (1 << 3)
1374 #define RHF_SGI_ONLY (1 << 4)
1375 #define RHF_GUARANTEE_INIT (1 << 5)
1376 #define RHF_DELTA_C_PLUS_PLUS (1 << 6)
1377 #define RHF_GUARANTEE_START_INIT (1 << 7)
1378 #define RHF_PIXIE (1 << 8)
1379 #define RHF_DEFAULT_DELAY_LOAD (1 << 9)
1380 #define RHF_REQUICKSTART (1 << 10)
1381 #define RHF_REQUICKSTARTED (1 << 11)
1382 #define RHF_CORD (1 << 12)
1383 #define RHF_NO_UNRES_UNDEF (1 << 13)
1384 #define RHF_RLD_ORDER_SAFE (1 << 14)
1385
1386
1387
1388 typedef struct
1389 {
1390 Elf32_Word l_name;
1391 ;
1392 ;
1393 ;
1394 ;
1395 } Elf32_Lib;
1396
1397 typedef struct
1398 {
1399 Elf64_Word l_name;
1400 ;
1401 ;
1402 ;
1403 ;
1404 } Elf64_Lib;
1405
1406
1407
1408
1409 #define LL_NONE 0
1410 #define LL_EXACT_MATCH (1 << 0)
1411 #define LL_IGNORE_INT_VER (1 << 1)
1412 #define LL_REQUIRE_MINOR (1 << 2)
1413 #define LL_EXPORTS (1 << 3)
1414 #define LL_DELAY_LOAD (1 << 4)
1415 #define LL_DELTA (1 << 5)
1416
1417
1418
1419 typedef Elf32_Addr Elf32_Conflict;
1420
1421
1422
1423
1424
1425
1426 #define EF_PARISC_TRAPNL 1
1427 #define EF_PARISC_EXT 2
1428 #define EF_PARISC_ARCH 0xffff0000
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438 #define SHT_PARISC_GOT 0x70000000
1439 #define SHT_PARISC_ARCH 0x70000001
1440 #define SHT_PARISC_GLOBAL 0x70000002
1441 #define SHT_PARISC_MILLI 0x70000003
1442 #define SHT_PARISC_UNWIND 0x70000004
1443 #define SHT_PARISC_PLT 0x70000005
1444 #define SHT_PARISC_SDATA 0x70000006
1445 #define SHT_PARISC_SBSS 0x70000007
1446 #define SHT_PARISC_SYMEXTN 0x70000008
1447 #define SHT_PARISC_STUBS 0x70000009
1448
1449
1450
1451 #define SHF_PARISC_GLOBAL 0x10000000
1452 #define SHF_PARISC_SHORT 0x20000000
1453
1454
1455
1456 #define STT_PARISC_MILLICODE 13
1457
1458
1459
1460 #define R_PARISC_NONE 0
1461 #define R_PARISC_DIR32 1
1462 #define R_PARISC_DIR21L 2
1463 #define R_PARISC_DIR17R 3
1464 #define R_PARISC_DIR14R 4
1465 #define R_PARISC_PCREL21L 5
1466 #define R_PARISC_PCREL14R 6
1467 #define R_PARISC_PCREL17C 7
1468
1469 #define R_PARISC_PCREL17F 8
1470
1471 #define R_PARISC_DPREL21L 9
1472 #define R_PARISC_DPREL14R 10
1473 #define R_PARISC_DPREL14F 11
1474 #define R_PARISC_DLTREL21L 12
1475 #define R_PARISC_DLTREL14R 13
1476 #define R_PARISC_DLTREL14F 14
1477 #define R_PARISC_DLTIND21L 15
1478
1479 #define R_PARISC_DLTIND14R 16
1480
1481 #define R_PARISC_DLTIND14F 17
1482
1483 #define R_PARISC_PLABEL32 18
1484
1485
1486
1487
1488
1489 #define EF_ALPHA_32BIT 1
1490 #define EF_ALPHA_CANRELAX 2
1491
1492
1493
1494
1495 #define SHT_ALPHA_DEBUG 0x70000001
1496 #define SHT_ALPHA_REGINFO 0x70000002
1497
1498
1499
1500 #define SHF_ALPHA_GPREL 0x10000000
1501
1502
1503 #define STO_ALPHA_NOPV 0x80
1504 #define STO_ALPHA_STD_GPLOAD 0x88
1505
1506
1507
1508 #define R_ALPHA_NONE 0
1509 #define R_ALPHA_REFLONG 1
1510 #define R_ALPHA_REFQUAD 2
1511 #define R_ALPHA_GPREL32 3
1512 #define R_ALPHA_LITERAL 4
1513 #define R_ALPHA_LITUSE 5
1514 #define R_ALPHA_GPDISP 6
1515 #define R_ALPHA_BRADDR 7
1516 #define R_ALPHA_HINT 8
1517 #define R_ALPHA_SREL16 9
1518 #define R_ALPHA_SREL32 10
1519 #define R_ALPHA_SREL64 11
1520 #define R_ALPHA_OP_PUSH 12
1521 #define R_ALPHA_OP_STORE 13
1522 #define R_ALPHA_OP_PSUB 14
1523 #define R_ALPHA_OP_PRSHIFT 15
1524 #define R_ALPHA_GPVALUE 16
1525 #define R_ALPHA_GPRELHIGH 17
1526 #define R_ALPHA_GPRELLOW 18
1527 #define R_ALPHA_IMMED_GP_16 19
1528 #define R_ALPHA_IMMED_GP_HI32 20
1529 #define R_ALPHA_IMMED_SCN_HI32 21
1530 #define R_ALPHA_IMMED_BR_HI32 22
1531 #define R_ALPHA_IMMED_LO32 23
1532 #define R_ALPHA_COPY 24
1533 #define R_ALPHA_GLOB_DAT 25
1534 #define R_ALPHA_JMP_SLOT 26
1535 #define R_ALPHA_RELATIVE 27
1536
1537 #define R_ALPHA_NUM 28
1538
1539
1540
1541
1542
1543 #define R_PPC_NONE 0
1544 #define R_PPC_ADDR32 1
1545 #define R_PPC_ADDR24 2
1546 #define R_PPC_ADDR16 3
1547 #define R_PPC_ADDR16_LO 4
1548 #define R_PPC_ADDR16_HI 5
1549 #define R_PPC_ADDR16_HA 6
1550 #define R_PPC_ADDR14 7
1551 #define R_PPC_ADDR14_BRTAKEN 8
1552 #define R_PPC_ADDR14_BRNTAKEN 9
1553 #define R_PPC_REL24 10
1554 #define R_PPC_REL14 11
1555 #define R_PPC_REL14_BRTAKEN 12
1556 #define R_PPC_REL14_BRNTAKEN 13
1557 #define R_PPC_GOT16 14
1558 #define R_PPC_GOT16_LO 15
1559 #define R_PPC_GOT16_HI 16
1560 #define R_PPC_GOT16_HA 17
1561 #define R_PPC_PLTREL24 18
1562 #define R_PPC_COPY 19
1563 #define R_PPC_GLOB_DAT 20
1564 #define R_PPC_JMP_SLOT 21
1565 #define R_PPC_RELATIVE 22
1566 #define R_PPC_LOCAL24PC 23
1567 #define R_PPC_UADDR32 24
1568 #define R_PPC_UADDR16 25
1569 #define R_PPC_REL32 26
1570 #define R_PPC_PLT32 27
1571 #define R_PPC_PLTREL32 28
1572 #define R_PPC_PLT16_LO 29
1573 #define R_PPC_PLT16_HI 30
1574 #define R_PPC_PLT16_HA 31
1575 #define R_PPC_SDAREL16 32
1576 #define R_PPC_SECTOFF 33
1577 #define R_PPC_SECTOFF_LO 34
1578 #define R_PPC_SECTOFF_HI 35
1579 #define R_PPC_SECTOFF_HA 36
1580
1581 #define R_PPC_NUMm 37
1582
1583
1584
1585 #define R_PPC_EMB_NADDR32 101
1586 #define R_PPC_EMB_NADDR16 102
1587 #define R_PPC_EMB_NADDR16_LO 103
1588 #define R_PPC_EMB_NADDR16_HI 104
1589 #define R_PPC_EMB_NADDR16_HA 105
1590 #define R_PPC_EMB_SDAI16 106
1591 #define R_PPC_EMB_SDA2I16 107
1592 #define R_PPC_EMB_SDA2REL 108
1593 #define R_PPC_EMB_SDA21 109
1594 #define R_PPC_EMB_MRKREF 110
1595 #define R_PPC_EMB_RELSEC16 111
1596 #define R_PPC_EMB_RELST_LO 112
1597 #define R_PPC_EMB_RELST_HI 113
1598 #define R_PPC_EMB_RELST_HA 114
1599 #define R_PPC_EMB_BIT_FLD 115
1600 #define R_PPC_EMB_RELSDA 116
1601
1602
1603 #define R_PPC_DIAB_SDA21_LO 180
1604 #define R_PPC_DIAB_SDA21_HI 181
1605 #define R_PPC_DIAB_SDA21_HA 182
1606 #define R_PPC_DIAB_RELSDA_LO 183
1607 #define R_PPC_DIAB_RELSDA_HI 184
1608 #define R_PPC_DIAB_RELSDA_HA 185
1609
1610
1611
1612 #define R_PPC_TOC16 255
1613
1614
1615
1616
1617
1618 #define EF_ARM_RELEXEC 0x01
1619 #define EF_ARM_HASENTRY 0x02
1620 #define EF_ARM_INTERWORK 0x04
1621 #define EF_ARM_APCS_26 0x08
1622 #define EF_ARM_APCS_FLOAT 0x10
1623 #define EF_ARM_PIC 0x20
1624 #define EF_ALIGN8 0x40
1625 #define EF_NEW_ABI 0x80
1626 #define EF_OLD_ABI 0x100
1627
1628
1629 #define STT_ARM_TFUNC 0xd
1630
1631
1632 #define SHF_ARM_ENTRYSECT 0x10000000
1633 #define SHF_ARM_COMDEF 0x80000000
1634
1635
1636
1637 #define PF_ARM_SB 0x10000000
1638
1639
1640
1641 #define R_ARM_NONE 0
1642 #define R_ARM_PC24 1
1643 #define R_ARM_ABS32 2
1644 #define R_ARM_REL32 3
1645 #define R_ARM_PC13 4
1646 #define R_ARM_ABS16 5
1647 #define R_ARM_ABS12 6
1648 #define R_ARM_THM_ABS5 7
1649 #define R_ARM_ABS8 8
1650 #define R_ARM_SBREL32 9
1651 #define R_ARM_THM_PC22 10
1652 #define R_ARM_THM_PC8 11
1653 #define R_ARM_AMP_VCALL9 12
1654 #define R_ARM_SWI24 13
1655 #define R_ARM_THM_SWI8 14
1656 #define R_ARM_XPC25 15
1657 #define R_ARM_THM_XPC22 16
1658 #define R_ARM_COPY 20
1659 #define R_ARM_GLOB_DAT 21
1660 #define R_ARM_JUMP_SLOT 22
1661 #define R_ARM_RELATIVE 23
1662 #define R_ARM_GOTOFF 24
1663 #define R_ARM_GOTPC 25
1664 #define R_ARM_GOT32 26
1665 #define R_ARM_PLT32 27
1666 #define R_ARM_GNU_VTENTRY 100
1667 #define R_ARM_GNU_VTINHERIT 101
1668 #define R_ARM_THM_PC11 102
1669 #define R_ARM_THM_PC9 103
1670 #define R_ARM_RXPC25 249
1671 #define R_ARM_RSBREL32 250
1672 #define R_ARM_THM_RPC22 251
1673 #define R_ARM_RREL32 252
1674 #define R_ARM_RABS22 253
1675 #define R_ARM_RPC24 254
1676 #define R_ARM_RBASE 255
1677
1678 #define R_ARM_NUM 256
1679
1680
1681
1682
1683
1684 #define R_C60_32 1
1685 #define R_C60_GOT32 3
1686 #define R_C60_PLT32 4
1687 #define R_C60_COPY 5
1688 #define R_C60_GLOB_DAT 6
1689 #define R_C60_JMP_SLOT 7
1690 #define R_C60_RELATIVE 8
1691 #define R_C60_GOTOFF 9
1692 #define R_C60_GOTPC 10
1693
1694 #define R_C60HI16 0x55
1695 #define R_C60LO16 0x54
1696
1697 #endif
1698
1699
1700
1701
1702
1703
1704 #ifndef __GNU_STAB__
1705
1706
1707
1708 #define __GNU_STAB__
1709
1710 #define __define_stab(NAME, CODE, STRING) NAME=CODE,
1711
1712 enum __stab_debug_code
1713 {
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740 (N_GSYM, 0x20, "GSYM")
1741
1742
1743
1744 (N_FNAME, 0x22, "FNAME")
1745
1746
1747
1748
1749 (N_FUN, 0x24, "FUN")
1750
1751
1752
1753 (N_STSYM, 0x26, "STSYM")
1754
1755
1756 (N_LCSYM, 0x28, "LCSYM")
1757
1758
1759
1760 (N_MAIN, 0x2a, "MAIN")
1761
1762
1763
1764 (N_PC, 0x30, "PC")
1765
1766
1767 (N_NSYMS, 0x32, "NSYMS")
1768
1769
1770 (N_NOMAP, 0x34, "NOMAP")
1771
1772
1773
1774 (N_OBJ, 0x38, "OBJ")
1775
1776
1777
1778
1779 (N_OPT, 0x3c, "OPT")
1780
1781
1782 (N_RSYM, 0x40, "RSYM")
1783
1784
1785 (N_M2C, 0x42, "M2C")
1786
1787
1788
1789 (N_SLINE, 0x44, "SLINE")
1790
1791
1792 (N_DSLINE, 0x46, "DSLINE")
1793
1794
1795 (N_BSLINE, 0x48, "BSLINE")
1796
1797
1798
1799
1800 (N_BROWS, 0x48, "BROWS")
1801
1802
1803
1804
1805
1806 (N_DEFD, 0x4a, "DEFD")
1807
1808
1809
1810
1811 (N_EHDECL, 0x50, "EHDECL")
1812
1813 (N_MOD2, 0x50, "MOD2")
1814
1815
1816
1817
1818
1819
1820 (N_CATCH, 0x54, "CATCH")
1821
1822
1823 (N_SSYM, 0x60, "SSYM")
1824
1825
1826
1827 (N_SO, 0x64, "SO")
1828
1829
1830
1831 (N_LSYM, 0x80, "LSYM")
1832
1833
1834
1835
1836 (N_BINCL, 0x82, "BINCL")
1837
1838
1839
1840 (N_SOL, 0x84, "SOL")
1841
1842
1843
1844 (N_PSYM, 0xa0, "PSYM")
1845
1846
1847
1848
1849
1850 (N_EINCL, 0xa2, "EINCL")
1851
1852
1853 (N_ENTRY, 0xa4, "ENTRY")
1854
1855
1856
1857
1858
1859 (N_LBRAC, 0xc0, "LBRAC")
1860
1861
1862
1863
1864
1865 (N_EXCL, 0xc2, "EXCL")
1866
1867
1868 (N_SCOPE, 0xc4, "SCOPE")
1869
1870
1871
1872 (N_RBRAC, 0xe0, "RBRAC")
1873
1874
1875 (N_BCOMM, 0xe2, "BCOMM")
1876
1877
1878
1879 (N_ECOMM, 0xe4, "ECOMM")
1880
1881
1882
1883 (N_ECOML, 0xe8, "ECOML")
1884
1885
1886
1887
1888 (N_NBTEXT, 0xF0, "NBTEXT")
1889 __define_stab (N_NBDATA, 0xF2, "NBDATA")
1890 __define_stab (N_NBBSS, 0xF4, "NBBSS")
1891 __define_stab (N_NBSTS, 0xF6, "NBSTS")
1892 __define_stab (N_NBLCS, 0xF8, "NBLCS")
1893
1894
1895
1896 (N_LENG, 0xfe, "LENG")
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952 LAST_UNUSED_STAB_CODE
1953 };
1954
1955 #undef __define_stab
1956
1957 #endif
1958
1959
1960 #ifndef O_BINARY
1961 #define O_BINARY 0
1962 #endif
1963
1964
1965
1966
1967 #ifndef LIBTCC_H
1968 #define LIBTCC_H
1969
1970 #ifdef __cplusplus
1971 extern "C" {
1972 #endif
1973
1974 struct TCCState;
1975
1976 typedef struct TCCState TCCState;
1977
1978
1979 *tcc_new(void);
1980
1981
1982 void tcc_delete(TCCState *s);
1983
1984
1985 void tcc_enable_debug(TCCState *s);
1986
1987
1988 void tcc_set_error_func(TCCState *s, void *error_opaque,
1989 void (*error_func)(void *opaque, const char *msg));
1990
1991
1992 int tcc_set_warning(TCCState *s, const char *warning_name, int value);
1993
1994
1995
1996
1997
1998 int tcc_add_include_path(TCCState *s, const char *pathname);
1999
2000
2001 int tcc_add_sysinclude_path(TCCState *s, const char *pathname);
2002
2003
2004 void tcc_define_symbol(TCCState *s, const char *sym, const char *value);
2005
2006
2007 void tcc_undefine_symbol(TCCState *s, const char *sym);
2008
2009
2010
2011
2012
2013
2014 int tcc_add_file(TCCState *s, const char *filename);
2015
2016
2017
2018 int tcc_compile_string(TCCState *s, const char *buf);
2019
2020
2021
2022
2023
2024 #define TCC_OUTPUT_MEMORY 0
2025
2026 #define TCC_OUTPUT_EXE 1
2027 #define TCC_OUTPUT_DLL 2
2028 #define TCC_OUTPUT_OBJ 3
2029 int tcc_set_output_type(TCCState *s, int output_type);
2030
2031 #define TCC_OUTPUT_FORMAT_ELF 0
2032 #define TCC_OUTPUT_FORMAT_BINARY 1
2033 #define TCC_OUTPUT_FORMAT_COFF 2
2034
2035
2036 int tcc_add_library_path(TCCState *s, const char *pathname);
2037
2038
2039 int tcc_add_library(TCCState *s, const char *libraryname);
2040
2041
2042 int tcc_add_symbol(TCCState *s, const char *name, unsigned long val);
2043
2044
2045
2046 int tcc_output_file(TCCState *s, const char *filename);
2047
2048
2049
2050 int tcc_run(TCCState *s, int argc, char **argv);
2051
2052
2053
2054 int tcc_relocate(TCCState *s);
2055
2056
2057 int tcc_get_symbol(TCCState *s, unsigned long *pval, const char *name);
2058
2059 #ifdef __cplusplus
2060 }
2061 #endif
2062
2063 #endif
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \
2085 !defined(TCC_TARGET_C67)
2086 #define TCC_TARGET_I386
2087 #endif
2088
2089 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_ARM) && \
2090 !defined(TCC_TARGET_C67)
2091 #define CONFIG_TCC_BCHECK
2092 #endif
2093
2094 #if defined(WIN32) && !defined(TCC_TARGET_PE)
2095 #define CONFIG_TCC_STATIC
2096 #endif
2097
2098
2099 #if !defined(TCC_TARGET_ARM) && !defined(TCC_TARGET_C67)
2100 #define CONFIG_TCC_ASM
2101 #endif
2102
2103
2104 #if defined(TCC_TARGET_C67)
2105 #define TCC_TARGET_COFF
2106 #endif
2107
2108 #define FALSE 0
2109 #define false 0
2110 #define TRUE 1
2111 #define true 1
2112 typedef int BOOL;
2113
2114
2115
2116 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
2117
2118 #define INCLUDE_STACK_SIZE 32
2119 #define IFDEF_STACK_SIZE 64
2120 #define VSTACK_SIZE 256
2121 #define STRING_MAX_SIZE 1024
2122 #define PACK_STACK_SIZE 8
2123
2124 #define TOK_HASH_SIZE 8192
2125 #define TOK_ALLOC_INCR 512
2126 #define TOK_MAX_SIZE 4
2127
2128
2129 typedef struct TokenSym {
2130 struct TokenSym *hash_next;
2131 struct Sym *sym_define;
2132 struct Sym *sym_label;
2133 struct Sym *sym_struct;
2134 struct Sym *sym_identifier;
2135 int tok;
2136 int len;
2137 char str[1];
2138 } TokenSym;
2139
2140 typedef struct CString {
2141 int size;
2142 void *data;
2143 int size_allocated;
2144 void *data_allocated;
2145 } CString;
2146
2147
2148 typedef struct CType {
2149 int t;
2150 struct Sym *ref;
2151 } CType;
2152
2153
2154 typedef union CValue {
2155 long double ld;
2156 double d;
2157 float f;
2158 int i;
2159 unsigned int ui;
2160 unsigned int ul;
2161 long long ll;
2162 unsigned long long ull;
2163 struct CString *cstr;
2164 void *ptr;
2165 int tab[1];
2166 } CValue;
2167
2168
2169 typedef struct SValue {
2170 CType type;
2171 unsigned short r;
2172 unsigned short r2;
2173
2174 ;
2175 struct Sym *sym;
2176 } SValue;
2177
2178
2179 typedef struct Sym {
2180 long v;
2181 long r;
2182 long c;
2183 ;
2184 struct Sym *next;
2185 struct Sym *prev;
2186 struct Sym *prev_tok;
2187 } Sym;
2188
2189
2190
2191
2192
2193 #define SHF_PRIVATE 0x80000000
2194
2195 typedef struct Section {
2196 unsigned long data_offset;
2197 unsigned char *data;
2198 unsigned long data_allocated;
2199 int sh_name;
2200 int sh_num;
2201 int sh_type;
2202 int sh_flags;
2203 int sh_info;
2204 int sh_addralign;
2205 int sh_entsize;
2206 unsigned long sh_size;
2207 unsigned long sh_addr;
2208 unsigned long sh_offset;
2209 int nb_hashed_syms;
2210 struct Section *link;
2211 struct Section *reloc;
2212 struct Section *hash;
2213 struct Section *next;
2214 char name[1];
2215 } Section;
2216
2217 typedef struct DLLReference {
2218 int level;
2219 char name[1];
2220 } DLLReference;
2221
2222
2223 typedef struct AttributeDef {
2224 int aligned;
2225 int packed;
2226 Section *section;
2227 unsigned char func_call;
2228 unsigned char dllexport;
2229 } AttributeDef;
2230
2231 #define SYM_STRUCT 0x40000000
2232 #define SYM_FIELD 0x20000000
2233 #define SYM_FIRST_ANOM 0x10000000
2234
2235
2236 #define FUNC_NEW 1
2237 #define FUNC_OLD 2
2238 #define FUNC_ELLIPSIS 3
2239
2240
2241 #define FUNC_CDECL 0
2242 #define FUNC_STDCALL 1
2243 #define FUNC_FASTCALL1 2
2244 #define FUNC_FASTCALL2 3
2245 #define FUNC_FASTCALL3 4
2246
2247
2248 #define MACRO_OBJ 0
2249 #define MACRO_FUNC 1
2250
2251
2252 #define LABEL_DEFINED 0
2253 #define LABEL_FORWARD 1
2254 #define LABEL_DECLARED 2
2255
2256
2257 #define TYPE_ABSTRACT 1
2258 #define TYPE_DIRECT 2
2259
2260 #define IO_BUF_SIZE 8192
2261
2262 typedef struct BufferedFile {
2263 uint8_t *buf_ptr;
2264 uint8_t *buf_end;
2265 int fd;
2266 int line_num;
2267 int ifndef_macro;
2268 int ifndef_macro_saved;
2269 int *ifdef_stack_ptr;
2270 char inc_type;
2271 char inc_filename[512];
2272 char filename[1024];
2273 unsigned char buffer[IO_BUF_SIZE + 1];
2274 } BufferedFile;
2275
2276 #define CH_EOB '\\'
2277 #define CH_EOF (-1)
2278
2279
2280
2281 typedef struct ParseState {
2282 int *macro_ptr;
2283 int line_num;
2284 int tok;
2285 CValue tokc;
2286 } ParseState;
2287
2288
2289 typedef struct TokenString {
2290 int *str;
2291 int len;
2292 int allocated_len;
2293 int last_line_num;
2294 } TokenString;
2295
2296
2297
2298 typedef struct CachedInclude {
2299 int ifndef_macro;
2300 int hash_next;
2301 char type;
2302 char filename[1];
2303 } CachedInclude;
2304
2305 #define CACHED_INCLUDES_HASH_SIZE 512
2306
2307
2308 static struct BufferedFile *file;
2309 static int ch, tok;
2310 static CValue tokc;
2311 static CString tokcstr;
2312
2313 static int tok_flags;
2314 #define TOK_FLAG_BOL 0x0001
2315 #define TOK_FLAG_BOF 0x0002
2316 #define TOK_FLAG_ENDIF 0x0004
2317
2318 static int *macro_ptr, *macro_ptr_allocated;
2319 static int *unget_saved_macro_ptr;
2320 static int unget_saved_buffer[TOK_MAX_SIZE + 1];
2321 static int unget_buffer_enabled;
2322 static int parse_flags;
2323 #define PARSE_FLAG_PREPROCESS 0x0001
2324 #define PARSE_FLAG_TOK_NUM 0x0002
2325 #define PARSE_FLAG_LINEFEED 0x0004
2326
2327
2328 #define PARSE_FLAG_ASM_COMMENTS 0x0008
2329
2330 static Section *text_section, *data_section, *bss_section;
2331 static Section *cur_text_section;
2332
2333 #ifdef CONFIG_TCC_ASM
2334 static Section *last_text_section;
2335 #endif
2336
2337 static Section *bounds_section;
2338 static Section *lbounds_section;
2339
2340 static Section *symtab_section, *strtab_section;
2341
2342
2343 static Section *stab_section, *stabstr_section;
2344
2345
2346
2347
2348
2349
2350 static long rsym, anon_sym, ind, loc;
2351
2352 static int const_wanted;
2353 static int nocode_wanted;
2354 static int global_expr;
2355
2356 static CType func_vt;
2357
2358 static int func_vc;
2359 static long last_line_num, last_ind, func_ind;
2360 static int tok_ident;
2361 static TokenSym **table_ident;
2362 static TokenSym *hash_ident[TOK_HASH_SIZE];
2363 static char token_buf[STRING_MAX_SIZE + 1];
2364 static char *funcname;
2365 static Sym *global_stack, *local_stack;
2366 static Sym *define_stack;
2367 static Sym *global_label_stack, *local_label_stack;
2368
2369 #define SYM_POOL_NB (8192 / sizeof(Sym))
2370 static Sym *sym_free_first;
2371
2372 static SValue vstack[VSTACK_SIZE], *vtop;
2373
2374 static CType char_pointer_type, func_old_type, int_type;
2375
2376 static unsigned char isidnum_table[256];
2377
2378
2379 static int do_debug = 0;
2380
2381
2382 static int do_bounds_check = 0;
2383
2384
2385 #if !defined(LIBTCC)
2386 static int do_bench = 0;
2387 #endif
2388 static int total_lines;
2389 static int total_bytes;
2390
2391
2392 static int gnu_ext = 1;
2393
2394
2395 static int tcc_ext = 1;
2396
2397
2398 static int num_callers = 6;
2399 static const char **rt_bound_error_msg;
2400
2401
2402 static struct TCCState *tcc_state;
2403
2404
2405 static const char *tcc_lib_path = CONFIG_TCCDIR;
2406
2407 struct TCCState {
2408 int output_type;
2409
2410 BufferedFile **include_stack_ptr;
2411 int *ifdef_stack_ptr;
2412
2413
2414 char **include_paths;
2415 int nb_include_paths;
2416 char **sysinclude_paths;
2417 int nb_sysinclude_paths;
2418 CachedInclude **cached_includes;
2419 int nb_cached_includes;
2420
2421 char **library_paths;
2422 int nb_library_paths;
2423
2424
2425
2426 **loaded_dlls;
2427 int nb_loaded_dlls;
2428
2429
2430 **sections;
2431 int nb_sections;
2432
2433
2434 *got;
2435 Section *plt;
2436 unsigned long *got_offsets;
2437 int nb_got_offsets;
2438
2439 int *symtab_to_dynsym;
2440
2441
2442 *dynsymtab_section;
2443
2444 *dynsym;
2445
2446 int nostdinc;
2447 int nostdlib;
2448
2449 int nocommon;
2450
2451
2452 int static_link;
2453
2454
2455 int rdynamic;
2456
2457
2458 int alacarte_link;
2459
2460
2461 unsigned long text_addr;
2462 int has_text_addr;
2463
2464
2465 int output_format;
2466
2467
2468 int char_is_unsigned;
2469 int leading_underscore;
2470
2471
2472 int warn_write_strings;
2473 int warn_unsupported;
2474 int warn_error;
2475 int warn_none;
2476 int warn_implicit_function_declaration;
2477
2478
2479 void *error_opaque;
2480 void (*error_func)(void *opaque, const char *msg);
2481 int error_set_jmp_enabled;
2482 jmp_buf error_jmp_buf;
2483 int nb_errors;
2484
2485
2486 *asm_labels;
2487
2488
2489 *include_stack[INCLUDE_STACK_SIZE];
2490
2491
2492 int ifdef_stack[IFDEF_STACK_SIZE];
2493
2494
2495 int cached_includes_hash[CACHED_INCLUDES_HASH_SIZE];
2496
2497
2498 int pack_stack[PACK_STACK_SIZE];
2499 int *pack_stack_ptr;
2500 };
2501
2502
2503 #define VT_VALMASK 0x00ff
2504 #define VT_CONST 0x00f0
2505
2506 #define VT_LLOCAL 0x00f1
2507 #define VT_LOCAL 0x00f2
2508 #define VT_CMP 0x00f3
2509 #define VT_JMP 0x00f4
2510 #define VT_JMPI 0x00f5
2511 #define VT_LVAL 0x0100
2512 #define VT_SYM 0x0200
2513 #define VT_MUSTCAST 0x0400
2514
2515 #define VT_MUSTBOUND 0x0800
2516
2517 #define VT_BOUNDED 0x8000
2518
2519 #define VT_LVAL_BYTE 0x1000
2520 #define VT_LVAL_SHORT 0x2000
2521 #define VT_LVAL_UNSIGNED 0x4000
2522 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
2523
2524
2525 #define VT_INT 0
2526 #define VT_BYTE 1
2527 #define VT_SHORT 2
2528 #define VT_VOID 3
2529 #define VT_PTR 4
2530 #define VT_ENUM 5
2531 #define VT_FUNC 6
2532 #define VT_STRUCT 7
2533 #define VT_FLOAT 8
2534 #define VT_DOUBLE 9
2535 #define VT_LDOUBLE 10
2536 #define VT_BOOL 11
2537 #define VT_LLONG 12
2538 #define VT_LONG 13
2539
2540 #define VT_BTYPE 0x000f
2541 #define VT_UNSIGNED 0x0010
2542 #define VT_ARRAY 0x0020
2543 #define VT_BITFIELD 0x0040
2544 #define VT_CONSTANT 0x0800
2545 #define VT_VOLATILE 0x1000
2546 #define VT_SIGNED 0x2000
2547
2548
2549 #define VT_EXTERN 0x00000080
2550 #define VT_STATIC 0x00000100
2551 #define VT_TYPEDEF 0x00000200
2552 #define VT_INLINE 0x00000400
2553
2554 #define VT_STRUCT_SHIFT 16
2555
2556
2557 #define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
2558 #define VT_TYPE (~(VT_STORAGE))
2559
2560
2561
2562
2563 #define TOK_ULT 0x92
2564 #define TOK_UGE 0x93
2565 #define TOK_EQ 0x94
2566 #define TOK_NE 0x95
2567 #define TOK_ULE 0x96
2568 #define TOK_UGT 0x97
2569 #define TOK_LT 0x9c
2570 #define TOK_GE 0x9d
2571 #define TOK_LE 0x9e
2572 #define TOK_GT 0x9f
2573
2574 #define TOK_LAND 0xa0
2575 #define TOK_LOR 0xa1
2576
2577 #define TOK_DEC 0xa2
2578 #define TOK_MID 0xa3
2579 #define TOK_INC 0xa4
2580 #define TOK_UDIV 0xb0
2581 #define TOK_UMOD 0xb1
2582 #define TOK_PDIV 0xb2
2583 #define TOK_CINT 0xb3
2584 #define TOK_CCHAR 0xb4
2585 #define TOK_STR 0xb5
2586 #define TOK_TWOSHARPS 0xb6
2587 #define TOK_LCHAR 0xb7
2588 #define TOK_LSTR 0xb8
2589 #define TOK_CFLOAT 0xb9
2590 #define TOK_LINENUM 0xba
2591 #define TOK_CDOUBLE 0xc0
2592 #define TOK_CLDOUBLE 0xc1
2593 #define TOK_UMULL 0xc2
2594 #define TOK_ADDC1 0xc3
2595 #define TOK_ADDC2 0xc4
2596 #define TOK_SUBC1 0xc5
2597 #define TOK_SUBC2 0xc6
2598 #define TOK_CUINT 0xc8
2599 #define TOK_CLLONG 0xc9
2600 #define TOK_CULLONG 0xca
2601 #define TOK_ARROW 0xcb
2602 #define TOK_DOTS 0xcc
2603 #define TOK_SHR 0xcd
2604 #define TOK_PPNUM 0xce
2605
2606 #define TOK_SHL 0x01
2607 #define TOK_SAR 0x02
2608
2609
2610 #define TOK_A_MOD 0xa5
2611 #define TOK_A_AND 0xa6
2612 #define TOK_A_MUL 0xaa
2613 #define TOK_A_ADD 0xab
2614 #define TOK_A_SUB 0xad
2615 #define TOK_A_DIV 0xaf
2616 #define TOK_A_XOR 0xde
2617 #define TOK_A_OR 0xfc
2618 #define TOK_A_SHL 0x81
2619 #define TOK_A_SAR 0x82
2620
2621 #ifndef offsetof
2622 #define offsetof(type, field) ((size_t) &((type *)0)->field)
2623 #endif
2624
2625 #ifndef countof
2626 #define countof(tab) (sizeof(tab) / sizeof((tab)[0]))
2627 #endif
2628
2629
2630 static char tok_two_chars[] = "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
2631
2632 #define TOK_EOF (-1)
2633 #define TOK_LINEFEED 10
2634
2635
2636 #define TOK_IDENT 256
2637
2638
2639 #define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x)
2640
2641 #define DEF_BWL(x) \
2642 DEF(TOK_ASM_ ## x ## b, #x "b") \
2643 DEF(TOK_ASM_ ## x ## w, #x "w") \
2644 DEF(TOK_ASM_ ## x ## l, #x "l") \
2645 DEF(TOK_ASM_ ## x, #x)
2646
2647 #define DEF_WL(x) \
2648 DEF(TOK_ASM_ ## x ## w, #x "w") \
2649 DEF(TOK_ASM_ ## x ## l, #x "l") \
2650 DEF(TOK_ASM_ ## x, #x)
2651
2652 #define DEF_FP1(x) \
2653 DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \
2654 DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \
2655 DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \
2656 DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s")
2657
2658 #define DEF_FP(x) \
2659 DEF(TOK_ASM_ ## f ## x, "f" #x ) \
2660 DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \
2661 DEF_FP1(x)
2662
2663 #define DEF_ASMTEST(x) \
2664 DEF_ASM(x ## o) \
2665 DEF_ASM(x ## no) \
2666 DEF_ASM(x ## b) \
2667 DEF_ASM(x ## c) \
2668 DEF_ASM(x ## nae) \
2669 DEF_ASM(x ## nb) \
2670 DEF_ASM(x ## nc) \
2671 DEF_ASM(x ## ae) \
2672 DEF_ASM(x ## e) \
2673 DEF_ASM(x ## z) \
2674 DEF_ASM(x ## ne) \
2675 DEF_ASM(x ## nz) \
2676 DEF_ASM(x ## be) \
2677 DEF_ASM(x ## na) \
2678 DEF_ASM(x ## nbe) \
2679 DEF_ASM(x ## a) \
2680 DEF_ASM(x ## s) \
2681 DEF_ASM(x ## ns) \
2682 DEF_ASM(x ## p) \
2683 DEF_ASM(x ## pe) \
2684 DEF_ASM(x ## np) \
2685 DEF_ASM(x ## po) \
2686 DEF_ASM(x ## l) \
2687 DEF_ASM(x ## nge) \
2688 DEF_ASM(x ## nl) \
2689 DEF_ASM(x ## ge) \
2690 DEF_ASM(x ## le) \
2691 DEF_ASM(x ## ng) \
2692 DEF_ASM(x ## nle) \
2693 DEF_ASM(x ## g)
2694
2695 #define TOK_ASM_int TOK_INT
2696
2697 enum tcc_token {
2698 TOK_LAST = TOK_IDENT - 1,
2699 #define DEF(id, str) id,
2700
2701
2702
2703
2704 (TOK_INT, "int")
2705 DEF(TOK_VOID, "void")
2706 DEF(TOK_CHAR, "char")
2707 DEF(TOK_IF, "if")
2708 DEF(TOK_ELSE, "else")
2709 DEF(TOK_WHILE, "while")
2710 DEF(TOK_BREAK, "break")
2711 DEF(TOK_RETURN, "return")
2712 DEF(TOK_FOR, "for")
2713 DEF(TOK_EXTERN, "extern")
2714 DEF(TOK_STATIC, "static")
2715 DEF(TOK_UNSIGNED, "unsigned")
2716 DEF(TOK_GOTO, "goto")
2717 DEF(TOK_DO, "do")
2718 DEF(TOK_CONTINUE, "continue")
2719 DEF(TOK_SWITCH, "switch")
2720 DEF(TOK_CASE, "case")
2721
2722 DEF(TOK_CONST1, "const")
2723 DEF(TOK_CONST2, "__const")
2724 (TOK_CONST3, "__const__")
2725 (TOK_VOLATILE1, "volatile")
2726 DEF(TOK_VOLATILE2, "__volatile")
2727 (TOK_VOLATILE3, "__volatile__")
2728 (TOK_LONG, "long")
2729 DEF(TOK_REGISTER, "register")
2730 DEF(TOK_SIGNED1, "signed")
2731 DEF(TOK_SIGNED2, "__signed")
2732 (TOK_SIGNED3, "__signed__")
2733 (TOK_AUTO, "auto")
2734 DEF(TOK_INLINE1, "inline")
2735 DEF(TOK_INLINE2, "__inline")
2736 (TOK_INLINE3, "__inline__")
2737 (TOK_RESTRICT1, "restrict")
2738 DEF(TOK_RESTRICT2, "__restrict")
2739 DEF(TOK_RESTRICT3, "__restrict__")
2740 DEF(TOK_EXTENSION, "__extension__")
2741
2742 (TOK_FLOAT, "float")
2743 DEF(TOK_DOUBLE, "double")
2744 DEF(TOK_BOOL, "_Bool")
2745 DEF(TOK_SHORT, "short")
2746 DEF(TOK_STRUCT, "struct")
2747 DEF(TOK_UNION, "union")
2748 DEF(TOK_TYPEDEF, "typedef")
2749 DEF(TOK_DEFAULT, "default")
2750 DEF(TOK_ENUM, "enum")
2751 DEF(TOK_SIZEOF, "sizeof")
2752 DEF(TOK_ATTRIBUTE1, "__attribute")
2753 DEF(TOK_ATTRIBUTE2, "__attribute__")
2754 DEF(TOK_ALIGNOF1, "__alignof")
2755 DEF(TOK_ALIGNOF2, "__alignof__")
2756 DEF(TOK_TYPEOF1, "typeof")
2757 DEF(TOK_TYPEOF2, "__typeof")
2758 DEF(TOK_TYPEOF3, "__typeof__")
2759 DEF(TOK_LABEL, "__label__")
2760 DEF(TOK_ASM1, "asm")
2761 DEF(TOK_ASM2, "__asm")
2762 DEF(TOK_ASM3, "__asm__")
2763
2764
2765
2766
2767 (TOK_DEFINE, "define")
2768 DEF(TOK_INCLUDE, "include")
2769 DEF(TOK_INCLUDE_NEXT, "include_next")
2770 DEF(TOK_IFDEF, "ifdef")
2771 DEF(TOK_IFNDEF, "ifndef")
2772 DEF(TOK_ELIF, "elif")
2773 DEF(TOK_ENDIF, "endif")
2774 DEF(TOK_DEFINED, "defined")
2775 DEF(TOK_UNDEF, "undef")
2776 DEF(TOK_ERROR, "error")
2777 DEF(TOK_WARNING, "warning")
2778 DEF(TOK_LINE, "line")
2779 DEF(TOK_PRAGMA, "pragma")
2780 DEF(TOK___LINE__, "__LINE__")
2781 DEF(TOK___FILE__, "__FILE__")
2782 DEF(TOK___DATE__, "__DATE__")
2783 DEF(TOK___TIME__, "__TIME__")
2784 DEF(TOK___FUNCTION__, "__FUNCTION__")
2785 DEF(TOK___VA_ARGS__, "__VA_ARGS__")
2786
2787
2788 (TOK___FUNC__, "__func__")
2789
2790
2791
2792 (TOK_SECTION1, "section")
2793 DEF(TOK_SECTION2, "__section__")
2794 DEF(TOK_ALIGNED1, "aligned")
2795 DEF(TOK_ALIGNED2, "__aligned__")
2796 DEF(TOK_PACKED1, "packed")
2797 DEF(TOK_PACKED2, "__packed__")
2798 DEF(TOK_UNUSED1, "unused")
2799 DEF(TOK_UNUSED2, "__unused__")
2800 DEF(TOK_CDECL1, "cdecl")
2801 DEF(TOK_CDECL2, "__cdecl")
2802 DEF(TOK_CDECL3, "__cdecl__")
2803 DEF(TOK_STDCALL1, "stdcall")
2804 DEF(TOK_STDCALL2, "__stdcall")
2805 DEF(TOK_STDCALL3, "__stdcall__")
2806 DEF(TOK_DLLEXPORT, "dllexport")
2807 DEF(TOK_NORETURN1, "noreturn")
2808 DEF(TOK_NORETURN2, "__noreturn__")
2809 DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p")
2810 DEF(TOK_builtin_constant_p, "__builtin_constant_p")
2811 DEF(TOK_REGPARM1, "regparm")
2812 DEF(TOK_REGPARM2, "__regparm__")
2813
2814
2815 (TOK_pack, "pack")
2816 #if !defined(TCC_TARGET_I386)
2817
2818 (TOK_ASM_push, "push")
2819 DEF(TOK_ASM_pop, "pop")
2820 #endif
2821
2822
2823 (TOK_memcpy, "memcpy")
2824 DEF(TOK_memset, "memset")
2825 DEF(TOK_alloca, "alloca")
2826 DEF(TOK___divdi3, "__divdi3")
2827 DEF(TOK___moddi3, "__moddi3")
2828 DEF(TOK___udivdi3, "__udivdi3")
2829 DEF(TOK___umoddi3, "__umoddi3")
2830 #if defined(TCC_TARGET_ARM)
2831 DEF(TOK___divsi3, "__divsi3")
2832 DEF(TOK___modsi3, "__modsi3")
2833 DEF(TOK___udivsi3, "__udivsi3")
2834 DEF(TOK___umodsi3, "__umodsi3")
2835 DEF(TOK___sardi3, "__ashrdi3")
2836 DEF(TOK___shrdi3, "__lshrdi3")
2837 DEF(TOK___shldi3, "__ashldi3")
2838 DEF(TOK___slltold, "__slltold")
2839 DEF(TOK___fixunssfsi, "__fixunssfsi")
2840 DEF(TOK___fixunsdfsi, "__fixunsdfsi")
2841 DEF(TOK___fixunsxfsi, "__fixunsxfsi")
2842 DEF(TOK___fixsfdi, "__fixsfdi")
2843 DEF(TOK___fixdfdi, "__fixdfdi")
2844 DEF(TOK___fixxfdi, "__fixxfdi")
2845 #elif defined(TCC_TARGET_C67)
2846 DEF(TOK__divi, "_divi")
2847 DEF(TOK__divu, "_divu")
2848 DEF(TOK__divf, "_divf")
2849 DEF(TOK__divd, "_divd")
2850 DEF(TOK__remi, "_remi")
2851 DEF(TOK__remu, "_remu")
2852 DEF(TOK___sardi3, "__sardi3")
2853 DEF(TOK___shrdi3, "__shrdi3")
2854 DEF(TOK___shldi3, "__shldi3")
2855 #else
2856
2857 (TOK___sardi3, "__sardi3")
2858 DEF(TOK___shrdi3, "__shrdi3")
2859 DEF(TOK___shldi3, "__shldi3")
2860 #endif
2861 DEF(TOK___tcc_int_fpu_control, "__tcc_int_fpu_control")
2862 DEF(TOK___tcc_fpu_control, "__tcc_fpu_control")
2863 DEF(TOK___ulltof, "__ulltof")
2864 DEF(TOK___ulltod, "__ulltod")
2865 DEF(TOK___ulltold, "__ulltold")
2866 DEF(TOK___fixunssfdi, "__fixunssfdi")
2867 DEF(TOK___fixunsdfdi, "__fixunsdfdi")
2868 DEF(TOK___fixunsxfdi, "__fixunsxfdi")
2869 DEF(TOK___chkstk, "__chkstk")
2870
2871
2872 #ifdef CONFIG_TCC_BCHECK
2873 DEF(TOK___bound_ptr_add, "__bound_ptr_add")
2874 DEF(TOK___bound_ptr_indir1, "__bound_ptr_indir1")
2875 DEF(TOK___bound_ptr_indir2, "__bound_ptr_indir2")
2876 DEF(TOK___bound_ptr_indir4, "__bound_ptr_indir4")
2877 DEF(TOK___bound_ptr_indir8, "__bound_ptr_indir8")
2878 DEF(TOK___bound_ptr_indir12, "__bound_ptr_indir12")
2879 DEF(TOK___bound_ptr_indir16, "__bound_ptr_indir16")
2880 DEF(TOK___bound_local_new, "__bound_local_new")
2881 DEF(TOK___bound_local_delete, "__bound_local_delete")
2882 DEF(TOK_malloc, "malloc")
2883 DEF(TOK_free, "free")
2884 DEF(TOK_realloc, "realloc")
2885 DEF(TOK_memalign, "memalign")
2886 DEF(TOK_calloc, "calloc")
2887 DEF(TOK_memmove, "memmove")
2888 DEF(TOK_strlen, "strlen")
2889 DEF(TOK_strcpy, "strcpy")
2890 #endif
2891
2892
2893
2894 (byte)
2895 DEF_ASM(align)
2896 DEF_ASM(skip)
2897 DEF_ASM(space)
2898 DEF_ASM(string)
2899 DEF_ASM(asciz)
2900 DEF_ASM(ascii)
2901 DEF_ASM(globl)
2902 DEF_ASM(global)
2903 DEF_ASM(text)
2904 DEF_ASM(data)
2905 DEF_ASM(bss)
2906 DEF_ASM(previous)
2907 DEF_ASM(fill)
2908 DEF_ASM(org)
2909 DEF_ASM(quad)
2910
2911 #ifdef TCC_TARGET_I386
2912
2913
2914 (al)
2915 DEF_ASM(cl)
2916 DEF_ASM(dl)
2917 DEF_ASM(bl)
2918 DEF_ASM(ah)
2919 DEF_ASM(ch)
2920 DEF_ASM(dh)
2921 DEF_ASM(bh)
2922 DEF_ASM(ax)
2923 DEF_ASM(cx)
2924 DEF_ASM(dx)
2925 DEF_ASM(bx)
2926 DEF_ASM(sp)
2927 DEF_ASM(bp)
2928 DEF_ASM(si)
2929 DEF_ASM(di)
2930 DEF_ASM(eax)
2931 DEF_ASM(ecx)
2932 DEF_ASM(edx)
2933 DEF_ASM(ebx)
2934 DEF_ASM(esp)
2935 DEF_ASM(ebp)
2936 DEF_ASM(esi)
2937 DEF_ASM(edi)
2938 DEF_ASM(mm0)
2939 DEF_ASM(mm1)
2940 DEF_ASM(mm2)
2941 DEF_ASM(mm3)
2942 DEF_ASM(mm4)
2943 DEF_ASM(mm5)
2944 DEF_ASM(mm6)
2945 DEF_ASM(mm7)
2946 DEF_ASM(xmm0)
2947 DEF_ASM(xmm1)
2948 DEF_ASM(xmm2)
2949 DEF_ASM(xmm3)
2950 DEF_ASM(xmm4)
2951 DEF_ASM(xmm5)
2952 DEF_ASM(xmm6)
2953 DEF_ASM(xmm7)
2954 DEF_ASM(cr0)
2955 DEF_ASM(cr1)
2956 DEF_ASM(cr2)
2957 DEF_ASM(cr3)
2958 DEF_ASM(cr4)
2959 DEF_ASM(cr5)
2960 DEF_ASM(cr6)
2961 DEF_ASM(cr7)
2962 DEF_ASM(tr0)
2963 DEF_ASM(tr1)
2964 DEF_ASM(tr2)
2965 DEF_ASM(tr3)
2966 DEF_ASM(tr4)
2967 DEF_ASM(tr5)
2968 DEF_ASM(tr6)
2969 DEF_ASM(tr7)
2970 DEF_ASM(db0)
2971 DEF_ASM(db1)
2972 DEF_ASM(db2)
2973 DEF_ASM(db3)
2974 DEF_ASM(db4)
2975 DEF_ASM(db5)
2976 DEF_ASM(db6)
2977 DEF_ASM(db7)
2978 DEF_ASM(dr0)
2979 DEF_ASM(dr1)
2980 DEF_ASM(dr2)
2981 DEF_ASM(dr3)
2982 DEF_ASM(dr4)
2983 DEF_ASM(dr5)
2984 DEF_ASM(dr6)
2985 DEF_ASM(dr7)
2986 DEF_ASM(es)
2987 DEF_ASM(cs)
2988 DEF_ASM(ss)
2989 DEF_ASM(ds)
2990 DEF_ASM(fs)
2991 DEF_ASM(gs)
2992 DEF_ASM(st)
2993
2994 DEF_BWL(mov)
2995
2996
2997 (add)
2998 DEF_BWL(or)
2999 DEF_BWL(adc)
3000 DEF_BWL(sbb)
3001 DEF_BWL(and)
3002 DEF_BWL(sub)
3003 DEF_BWL(xor)
3004 DEF_BWL(cmp)
3005
3006
3007 (inc)
3008 DEF_BWL(dec)
3009 DEF_BWL(not)
3010 DEF_BWL(neg)
3011 DEF_BWL(mul)
3012 DEF_BWL(imul)
3013 DEF_BWL(div)
3014 DEF_BWL(idiv)
3015
3016 DEF_BWL(xchg)
3017 DEF_BWL(test)
3018
3019
3020 (rol)
3021 DEF_BWL(ror)
3022 DEF_BWL(rcl)
3023 DEF_BWL(rcr)
3024 DEF_BWL(shl)
3025 DEF_BWL(shr)
3026 DEF_BWL(sar)
3027
3028 DEF_ASM(shldw)
3029 DEF_ASM(shldl)
3030 DEF_ASM(shld)
3031 DEF_ASM(shrdw)
3032 DEF_ASM(shrdl)
3033 DEF_ASM(shrd)
3034
3035 DEF_ASM(pushw)
3036 DEF_ASM(pushl)
3037 DEF_ASM(push)
3038 DEF_ASM(popw)
3039 DEF_ASM(popl)
3040 DEF_ASM(pop)
3041 DEF_BWL(in)
3042 DEF_BWL(out)
3043
3044 DEF_WL(movzb)
3045
3046 DEF_ASM(movzwl)
3047 DEF_ASM(movsbw)
3048 DEF_ASM(movsbl)
3049 DEF_ASM(movswl)
3050
3051 DEF_WL(lea)
3052
3053 DEF_ASM(les)
3054 DEF_ASM(lds)
3055 DEF_ASM(lss)
3056 DEF_ASM(lfs)
3057 DEF_ASM(lgs)
3058
3059 DEF_ASM(call)
3060 DEF_ASM(jmp)
3061 DEF_ASM(lcall)
3062 DEF_ASM(ljmp)
3063
3064 DEF_ASMTEST(j)
3065
3066 DEF_ASMTEST(set)
3067 DEF_ASMTEST(cmov)
3068
3069 DEF_WL(bsf)
3070 DEF_WL(bsr)
3071 DEF_WL(bt)
3072 DEF_WL(bts)
3073 DEF_WL(btr)
3074 DEF_WL(btc)
3075
3076 DEF_WL(lsl)
3077
3078
3079 (add)
3080 DEF_FP(mul)
3081
3082 DEF_ASM(fcom)
3083 DEF_ASM(fcom_1)
3084 (com)
3085
3086 DEF_FP(comp)
3087 DEF_FP(sub)
3088 DEF_FP(subr)
3089 DEF_FP(div)
3090 DEF_FP(divr)
3091
3092 DEF_BWL(xadd)
3093 DEF_BWL(cmpxchg)
3094
3095
3096 (cmps)
3097 DEF_BWL(scmp)
3098 DEF_BWL(ins)
3099 DEF_BWL(outs)
3100 DEF_BWL(lods)
3101 DEF_BWL(slod)
3102 DEF_BWL(movs)
3103 DEF_BWL(smov)
3104 DEF_BWL(scas)
3105 DEF_BWL(ssca)
3106 DEF_BWL(stos)
3107 DEF_BWL(ssto)
3108
3109
3110
3111 #define ALT(x)
3112 #define DEF_ASM_OP0(name, opcode) DEF_ASM(name)
3113 #define DEF_ASM_OP0L(name, opcode, group, instr_type)
3114 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0)
3115 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1)
3116 #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2)
3117
3118
3119
3120 (pusha, 0x60)
3121 (popa, 0x61)
3122 DEF_ASM_OP0(clc, 0xf8)
3123 DEF_ASM_OP0(cld, 0xfc)
3124 DEF_ASM_OP0(cli, 0xfa)
3125 DEF_ASM_OP0(clts, 0x0f06)
3126 DEF_ASM_OP0(cmc, 0xf5)
3127 DEF_ASM_OP0(lahf, 0x9f)
3128 DEF_ASM_OP0(sahf, 0x9e)
3129 DEF_ASM_OP0(pushfl, 0x9c)
3130 DEF_ASM_OP0(popfl, 0x9d)
3131 DEF_ASM_OP0(pushf, 0x9c)
3132 DEF_ASM_OP0(popf, 0x9d)
3133 DEF_ASM_OP0(stc, 0xf9)
3134 DEF_ASM_OP0(std, 0xfd)
3135 DEF_ASM_OP0(sti, 0xfb)
3136 DEF_ASM_OP0(aaa, 0x37)
3137 DEF_ASM_OP0(aas, 0x3f)
3138 DEF_ASM_OP0(daa, 0x27)
3139 DEF_ASM_OP0(das, 0x2f)
3140 DEF_ASM_OP0(aad, 0xd50a)
3141 DEF_ASM_OP0(aam, 0xd40a)
3142 DEF_ASM_OP0(cbw, 0x6698)
3143 DEF_ASM_OP0(cwd, 0x6699)
3144 DEF_ASM_OP0(cwde, 0x98)
3145 DEF_ASM_OP0(cdq, 0x99)
3146 DEF_ASM_OP0(cbtw, 0x6698)
3147 DEF_ASM_OP0(cwtl, 0x98)
3148 DEF_ASM_OP0(cwtd, 0x6699)
3149 DEF_ASM_OP0(cltd, 0x99)
3150 DEF_ASM_OP0(int3, 0xcc)
3151 DEF_ASM_OP0(into, 0xce)
3152 DEF_ASM_OP0(iret, 0xcf)
3153 DEF_ASM_OP0(rsm, 0x0faa)
3154 DEF_ASM_OP0(hlt, 0xf4)
3155 DEF_ASM_OP0(wait, 0x9b)
3156 DEF_ASM_OP0(nop, 0x90)
3157 DEF_ASM_OP0(xlat, 0xd7)
3158
3159
3160 (DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
3161 ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
3162
3163 ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
3164 ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
3165
3166 ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
3167 ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
3168
3169 ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
3170 ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
3171
3172 ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
3173 ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
3174
3175 ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
3176 ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
3177
3178
3179
3180 (DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
3181 ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
3182
3183 ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3184 ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3185
3186 ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3187 ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3188
3189 ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3190 ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3191
3192 ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3193 ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3194
3195
3196 (aword, 0x67)
3197 DEF_ASM_OP0(addr16, 0x67)
3198 DEF_ASM_OP0(word, 0x66)
3199 DEF_ASM_OP0(data16, 0x66)
3200 DEF_ASM_OP0(lock, 0xf0)
3201 DEF_ASM_OP0(rep, 0xf3)
3202 DEF_ASM_OP0(repe, 0xf3)
3203 DEF_ASM_OP0(repz, 0xf3)
3204 DEF_ASM_OP0(repne, 0xf2)
3205 DEF_ASM_OP0(repnz, 0xf2)
3206
3207 DEF_ASM_OP0(invd, 0x0f08)
3208 DEF_ASM_OP0(wbinvd, 0x0f09)
3209 DEF_ASM_OP0(cpuid, 0x0fa2)
3210 DEF_ASM_OP0(wrmsr, 0x0f30)
3211 DEF_ASM_OP0(rdtsc, 0x0f31)
3212 DEF_ASM_OP0(rdmsr, 0x0f32)
3213 DEF_ASM_OP0(rdpmc, 0x0f33)
3214 DEF_ASM_OP0(ud2, 0x0f0b)
3215
3216
3217 (DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
3218 ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
3219 ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
3220 ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3221 ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
3222 ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
3223
3224 ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
3225 ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
3226
3227 ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
3228 ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
3229 ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
3230 ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
3231 ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
3232 ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
3233
3234 ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
3235 ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
3236 ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
3237 ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
3238 ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
3239
3240 ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
3241 ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
3242 ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
3243 ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
3244 ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
3245
3246 ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
3247 ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
3248 ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
3249
3250 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
3251 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
3252 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
3253 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3254
3255 ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
3256 ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
3257 ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
3258 ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
3259
3260 ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
3261 ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
3262 ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
3263 ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
3264
3265 ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
3266
3267 ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3268 ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3269 ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3270 ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3271 ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3272
3273
3274 (DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
3275 (DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3276 ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
3277 ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
3278 ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
3279
3280 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3281 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
3282 ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
3283 ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
3284
3285 ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
3286 ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3287 ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
3288 ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3289
3290 ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3291 ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3292
3293 ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3294 ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3295
3296 ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
3297 ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
3298 ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
3299 ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
3300 ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
3301
3302 ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3303 ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
3304 ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3305 ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
3306
3307
3308 (DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
3309 ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
3310 ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
3311
3312 ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
3313 ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
3314 ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
3315 ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
3316 ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
3317 ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
3318
3319 ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
3320 ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
3321 ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
3322 ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
3323
3324 ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
3325 ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
3326 ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
3327 ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
3328
3329 ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
3330 ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
3331 DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
3332 DEF_ASM_OP0(leave, 0xc9)
3333 DEF_ASM_OP0(ret, 0xc3)
3334 ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
3335 DEF_ASM_OP0(lret, 0xcb)
3336 ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
3337
3338 ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
3339 DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
3340 DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
3341 DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
3342 DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
3343 DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
3344 DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
3345
3346
3347
3348 (DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
3349
3350 ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
3351 ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
3352 ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
3353 ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
3354 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
3355 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
3356 ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
3357 ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3358 ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3359 ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3360 ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3361
3362 DEF_ASM_OP0(fucompp, 0xdae9)
3363 DEF_ASM_OP0(ftst, 0xd9e4)
3364 DEF_ASM_OP0(fxam, 0xd9e5)
3365 DEF_ASM_OP0(fld1, 0xd9e8)
3366 DEF_ASM_OP0(fldl2t, 0xd9e9)
3367 DEF_ASM_OP0(fldl2e, 0xd9ea)
3368 DEF_ASM_OP0(fldpi, 0xd9eb)
3369 DEF_ASM_OP0(fldlg2, 0xd9ec)
3370 DEF_ASM_OP0(fldln2, 0xd9ed)
3371 DEF_ASM_OP0(fldz, 0xd9ee)
3372
3373 DEF_ASM_OP0(f2xm1, 0xd9f0)
3374 DEF_ASM_OP0(fyl2x, 0xd9f1)
3375 DEF_ASM_OP0(fptan, 0xd9f2)
3376 DEF_ASM_OP0(fpatan, 0xd9f3)
3377 DEF_ASM_OP0(fxtract, 0xd9f4)
3378 DEF_ASM_OP0(fprem1, 0xd9f5)
3379 DEF_ASM_OP0(fdecstp, 0xd9f6)
3380 DEF_ASM_OP0(fincstp, 0xd9f7)
3381 DEF_ASM_OP0(fprem, 0xd9f8)
3382 DEF_ASM_OP0(fyl2xp1, 0xd9f9)
3383 DEF_ASM_OP0(fsqrt, 0xd9fa)
3384 DEF_ASM_OP0(fsincos, 0xd9fb)
3385 DEF_ASM_OP0(frndint, 0xd9fc)
3386 DEF_ASM_OP0(fscale, 0xd9fd)
3387 DEF_ASM_OP0(fsin, 0xd9fe)
3388 DEF_ASM_OP0(fcos, 0xd9ff)
3389 DEF_ASM_OP0(fchs, 0xd9e0)
3390 DEF_ASM_OP0(fabs, 0xd9e1)
3391 DEF_ASM_OP0(fninit, 0xdbe3)
3392 DEF_ASM_OP0(fnclex, 0xdbe2)
3393 DEF_ASM_OP0(fnop, 0xd9d0)
3394 DEF_ASM_OP0(fwait, 0x9b)
3395
3396
3397 (fld, 0xd9c0, 0, OPC_REG, OPT_ST)
3398 DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
3399 DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
3400 ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
3401 DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
3402 DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
3403 DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
3404 DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
3405 DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
3406
3407
3408 (fst, 0xddd0, 0, OPC_REG, OPT_ST)
3409 DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
3410 DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
3411 DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
3412 ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
3413 DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
3414 DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
3415 DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
3416 DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
3417 DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
3418
3419 DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
3420 DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
3421 DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
3422 DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
3423 DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
3424
3425
3426 (fxch, 0xd9c9)
3427 ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
3428
3429
3430 (fucom, 0xdde0, 0, OPC_REG, OPT_ST )
3431 DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
3432
3433 DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
3434 DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
3435 DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
3436 DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
3437 DEF_ASM_OP0(fnstsw, 0xdfe0)
3438 ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
3439 ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
3440 DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
3441 ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
3442 ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
3443 DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
3444 DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
3445 DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
3446 DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
3447 DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
3448 DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
3449 DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
3450 DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
3451 DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
3452 DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
3453 DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
3454
3455
3456 (arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
3457 DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
3458 DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
3459 DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
3460 DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
3461 DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
3462 ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
3463 DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
3464 DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
3465 DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
3466 DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
3467 DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
3468 DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
3469 DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
3470 DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
3471
3472
3473 (bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
3474 ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
3475 ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
3476 DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
3477
3478 DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
3479 DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
3480
3481
3482 (cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
3483
3484
3485 (DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
3486
3487 DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3488 DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3489 DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3490 DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3491 DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3492 DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3493 DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3494 DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3495
3496 DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3497 DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3498 DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3499 DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3500
3501
3502 (emms, 0x0f77)
3503 (movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
3504 ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
3505 DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3506 ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
3507 DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3508 DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3509 DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3510 DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3511 DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3512 DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3513 DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3514 DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3515 DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3516 DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3517 DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3518 DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3519 DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3520 DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3521 DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3522 DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3523 DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3524 DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3525 DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3526 DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3527 DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3528 DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3529 DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3530 ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
3531 DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3532 ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
3533 DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3534 ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
3535 DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3536 ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
3537 DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3538 ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
3539 DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3540 ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
3541 DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3542 ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
3543 DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3544 ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
3545 DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3546 DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3547 DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3548 DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3549 DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3550 DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3551 DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3552 DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3553 DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3554 DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3555 DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3556 DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3557 DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3558 DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3559
3560 #undef ALT
3561 #undef DEF_ASM_OP0
3562 #undef DEF_ASM_OP0L
3563 #undef DEF_ASM_OP1
3564 #undef DEF_ASM_OP2
3565 #undef DEF_ASM_OP3
3566
3567
3568 #define ALT(x)
3569 #define DEF_ASM_OP0(name, opcode)
3570 #define DEF_ASM_OP0L(name, opcode, group, instr_type) DEF_ASM(name)
3571 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0) DEF_ASM(name)
3572 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) DEF_ASM(name)
3573 #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) DEF_ASM(name)
3574
3575
3576
3577 (pusha, 0x60)
3578 (popa, 0x61)
3579 DEF_ASM_OP0(clc, 0xf8)
3580 DEF_ASM_OP0(cld, 0xfc)
3581 DEF_ASM_OP0(cli, 0xfa)
3582 DEF_ASM_OP0(clts, 0x0f06)
3583 DEF_ASM_OP0(cmc, 0xf5)
3584 DEF_ASM_OP0(lahf, 0x9f)
3585 DEF_ASM_OP0(sahf, 0x9e)
3586 DEF_ASM_OP0(pushfl, 0x9c)
3587 DEF_ASM_OP0(popfl, 0x9d)
3588 DEF_ASM_OP0(pushf, 0x9c)
3589 DEF_ASM_OP0(popf, 0x9d)
3590 DEF_ASM_OP0(stc, 0xf9)
3591 DEF_ASM_OP0(std, 0xfd)
3592 DEF_ASM_OP0(sti, 0xfb)
3593 DEF_ASM_OP0(aaa, 0x37)
3594 DEF_ASM_OP0(aas, 0x3f)
3595 DEF_ASM_OP0(daa, 0x27)
3596 DEF_ASM_OP0(das, 0x2f)
3597 DEF_ASM_OP0(aad, 0xd50a)
3598 DEF_ASM_OP0(aam, 0xd40a)
3599 DEF_ASM_OP0(cbw, 0x6698)
3600 DEF_ASM_OP0(cwd, 0x6699)
3601 DEF_ASM_OP0(cwde, 0x98)
3602 DEF_ASM_OP0(cdq, 0x99)
3603 DEF_ASM_OP0(cbtw, 0x6698)
3604 DEF_ASM_OP0(cwtl, 0x98)
3605 DEF_ASM_OP0(cwtd, 0x6699)
3606 DEF_ASM_OP0(cltd, 0x99)
3607 DEF_ASM_OP0(int3, 0xcc)
3608 DEF_ASM_OP0(into, 0xce)
3609 DEF_ASM_OP0(iret, 0xcf)
3610 DEF_ASM_OP0(rsm, 0x0faa)
3611 DEF_ASM_OP0(hlt, 0xf4)
3612 DEF_ASM_OP0(wait, 0x9b)
3613 DEF_ASM_OP0(nop, 0x90)
3614 DEF_ASM_OP0(xlat, 0xd7)
3615
3616
3617 (DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
3618 ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
3619
3620 ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
3621 ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
3622
3623 ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
3624 ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
3625
3626 ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
3627 ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
3628
3629 ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
3630 ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
3631
3632 ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
3633 ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
3634
3635
3636
3637 (DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
3638 ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
3639
3640 ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3641 ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3642
3643 ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3644 ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3645
3646 ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3647 ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3648
3649 ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3650 ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3651
3652
3653 (aword, 0x67)
3654 DEF_ASM_OP0(addr16, 0x67)
3655 DEF_ASM_OP0(word, 0x66)
3656 DEF_ASM_OP0(data16, 0x66)
3657 DEF_ASM_OP0(lock, 0xf0)
3658 DEF_ASM_OP0(rep, 0xf3)
3659 DEF_ASM_OP0(repe, 0xf3)
3660 DEF_ASM_OP0(repz, 0xf3)
3661 DEF_ASM_OP0(repne, 0xf2)
3662 DEF_ASM_OP0(repnz, 0xf2)
3663
3664 DEF_ASM_OP0(invd, 0x0f08)
3665 DEF_ASM_OP0(wbinvd, 0x0f09)
3666 DEF_ASM_OP0(cpuid, 0x0fa2)
3667 DEF_ASM_OP0(wrmsr, 0x0f30)
3668 DEF_ASM_OP0(rdtsc, 0x0f31)
3669 DEF_ASM_OP0(rdmsr, 0x0f32)
3670 DEF_ASM_OP0(rdpmc, 0x0f33)
3671 DEF_ASM_OP0(ud2, 0x0f0b)
3672
3673
3674 (DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
3675 ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
3676 ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
3677 ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3678 ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
3679 ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
3680
3681 ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
3682 ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
3683
3684 ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
3685 ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
3686 ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
3687 ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
3688 ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
3689 ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
3690
3691 ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
3692 ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
3693 ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
3694 ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
3695 ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
3696
3697 ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
3698 ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
3699 ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
3700 ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
3701 ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
3702
3703 ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
3704 ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
3705 ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
3706
3707 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
3708 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
3709 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
3710 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3711
3712 ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
3713 ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
3714 ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
3715 ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
3716
3717 ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
3718 ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
3719 ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
3720 ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
3721
3722 ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
3723
3724 ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3725 ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3726 ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3727 ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3728 ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3729
3730
3731 (DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
3732 (DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3733 ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
3734 ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
3735 ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
3736
3737 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3738 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
3739 ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
3740 ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
3741
3742 ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
3743 ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3744 ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
3745 ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3746
3747 ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3748 ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3749
3750 ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3751 ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3752
3753 ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
3754 ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
3755 ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
3756 ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
3757 ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
3758
3759 ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3760 ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
3761 ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3762 ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
3763
3764
3765 (DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
3766 ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
3767 ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
3768
3769 ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
3770 ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
3771 ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
3772 ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
3773 ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
3774 ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
3775
3776 ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
3777 ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
3778 ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
3779 ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
3780
3781 ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
3782 ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
3783 ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
3784 ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
3785
3786 ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
3787 ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
3788 DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
3789 DEF_ASM_OP0(leave, 0xc9)
3790 DEF_ASM_OP0(ret, 0xc3)
3791 ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
3792 DEF_ASM_OP0(lret, 0xcb)
3793 ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
3794
3795 ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
3796 DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
3797 DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
3798 DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
3799 DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
3800 DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
3801 DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
3802
3803
3804
3805 (DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
3806
3807 ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
3808 ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
3809 ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
3810 ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
3811 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
3812 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
3813 ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
3814 ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3815 ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3816 ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3817 ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3818
3819 DEF_ASM_OP0(fucompp, 0xdae9)
3820 DEF_ASM_OP0(ftst, 0xd9e4)
3821 DEF_ASM_OP0(fxam, 0xd9e5)
3822 DEF_ASM_OP0(fld1, 0xd9e8)
3823 DEF_ASM_OP0(fldl2t, 0xd9e9)
3824 DEF_ASM_OP0(fldl2e, 0xd9ea)
3825 DEF_ASM_OP0(fldpi, 0xd9eb)
3826 DEF_ASM_OP0(fldlg2, 0xd9ec)
3827 DEF_ASM_OP0(fldln2, 0xd9ed)
3828 DEF_ASM_OP0(fldz, 0xd9ee)
3829
3830 DEF_ASM_OP0(f2xm1, 0xd9f0)
3831 DEF_ASM_OP0(fyl2x, 0xd9f1)
3832 DEF_ASM_OP0(fptan, 0xd9f2)
3833 DEF_ASM_OP0(fpatan, 0xd9f3)
3834 DEF_ASM_OP0(fxtract, 0xd9f4)
3835 DEF_ASM_OP0(fprem1, 0xd9f5)
3836 DEF_ASM_OP0(fdecstp, 0xd9f6)
3837 DEF_ASM_OP0(fincstp, 0xd9f7)
3838 DEF_ASM_OP0(fprem, 0xd9f8)
3839 DEF_ASM_OP0(fyl2xp1, 0xd9f9)
3840 DEF_ASM_OP0(fsqrt, 0xd9fa)
3841 DEF_ASM_OP0(fsincos, 0xd9fb)
3842 DEF_ASM_OP0(frndint, 0xd9fc)
3843 DEF_ASM_OP0(fscale, 0xd9fd)
3844 DEF_ASM_OP0(fsin, 0xd9fe)
3845 DEF_ASM_OP0(fcos, 0xd9ff)
3846 DEF_ASM_OP0(fchs, 0xd9e0)
3847 DEF_ASM_OP0(fabs, 0xd9e1)
3848 DEF_ASM_OP0(fninit, 0xdbe3)
3849 DEF_ASM_OP0(fnclex, 0xdbe2)
3850 DEF_ASM_OP0(fnop, 0xd9d0)
3851 DEF_ASM_OP0(fwait, 0x9b)
3852
3853
3854 (fld, 0xd9c0, 0, OPC_REG, OPT_ST)
3855 DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
3856 DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
3857 ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
3858 DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
3859 DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
3860 DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
3861 DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
3862 DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
3863
3864
3865 (fst, 0xddd0, 0, OPC_REG, OPT_ST)
3866 DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
3867 DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
3868 DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
3869 ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
3870 DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
3871 DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
3872 DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
3873 DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
3874 DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
3875
3876 DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
3877 DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
3878 DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
3879 DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
3880 DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
3881
3882
3883 (fxch, 0xd9c9)
3884 ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
3885
3886
3887 (fucom, 0xdde0, 0, OPC_REG, OPT_ST )
3888 DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
3889
3890 DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
3891 DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
3892 DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
3893 DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
3894 DEF_ASM_OP0(fnstsw, 0xdfe0)
3895 ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
3896 ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
3897 DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
3898 ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
3899 ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
3900 DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
3901 DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
3902 DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
3903 DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
3904 DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
3905 DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
3906 DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
3907 DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
3908 DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
3909 DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
3910 DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
3911
3912
3913 (arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
3914 DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
3915 DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
3916 DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
3917 DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
3918 DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
3919 ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
3920 DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
3921 DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
3922 DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
3923 DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
3924 DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
3925 DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
3926 DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
3927 DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
3928
3929
3930 (bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
3931 ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
3932 ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
3933 DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
3934
3935 DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
3936 DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
3937
3938
3939 (cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
3940
3941
3942 (DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
3943
3944 DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3945 DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3946 DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3947 DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3948 DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3949 DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3950 DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3951 DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3952
3953 DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3954 DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3955 DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3956 DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3957
3958
3959 (emms, 0x0f77)
3960 (movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
3961 ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
3962 DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3963 ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
3964 DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3965 DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3966 DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3967 DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3968 DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3969 DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3970 DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3971 DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3972 DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3973 DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3974 DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3975 DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3976 DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3977 DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3978 DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3979 DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3980 DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3981 DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3982 DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3983 DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3984 DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3985 DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3986 DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3987 ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
3988 DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3989 ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
3990 DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3991 ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
3992 DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3993 ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
3994 DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3995 ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
3996 DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3997 ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
3998 DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3999 ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
4000 DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4001 ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
4002 DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4003 DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4004 DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4005 DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4006 DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4007 DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4008 DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4009 DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4010 DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4011 DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4012 DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4013 DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4014 DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4015 DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4016
4017 #undef ALT
4018 #undef DEF_ASM_OP0
4019 #undef DEF_ASM_OP0L
4020 #undef DEF_ASM_OP1
4021 #undef DEF_ASM_OP2
4022 #undef DEF_ASM_OP3
4023
4024
4025 #endif
4026
4027 #undef DEF
4028 };
4029
4030 static const char tcc_keywords[] =
4031 #define DEF(id, str) str "\0"
4032
4033
4034
4035
4036 (TOK_INT, "int")
4037 DEF(TOK_VOID, "void")
4038 DEF(TOK_CHAR, "char")
4039 DEF(TOK_IF, "if")
4040 DEF(TOK_ELSE, "else")
4041 DEF(TOK_WHILE, "while")
4042 DEF(TOK_BREAK, "break")
4043 DEF(TOK_RETURN, "return")
4044 DEF(TOK_FOR, "for")
4045 DEF(TOK_EXTERN, "extern")
4046 DEF(TOK_STATIC, "static")
4047 DEF(TOK_UNSIGNED, "unsigned")
4048 DEF(TOK_GOTO, "goto")
4049 DEF(TOK_DO, "do")
4050 DEF(TOK_CONTINUE, "continue")
4051 DEF(TOK_SWITCH, "switch")
4052 DEF(TOK_CASE, "case")
4053
4054 DEF(TOK_CONST1, "const")
4055 DEF(TOK_CONST2, "__const")
4056 (TOK_CONST3, "__const__")
4057 (TOK_VOLATILE1, "volatile")
4058 DEF(TOK_VOLATILE2, "__volatile")
4059 (TOK_VOLATILE3, "__volatile__")
4060 (TOK_LONG, "long")
4061 DEF(TOK_REGISTER, "register")
4062 DEF(TOK_SIGNED1, "signed")
4063 DEF(TOK_SIGNED2, "__signed")
4064 (TOK_SIGNED3, "__signed__")
4065 (TOK_AUTO, "auto")
4066 DEF(TOK_INLINE1, "inline")
4067 DEF(TOK_INLINE2, "__inline")
4068 (TOK_INLINE3, "__inline__")
4069 (TOK_RESTRICT1, "restrict")
4070 DEF(TOK_RESTRICT2, "__restrict")
4071 DEF(TOK_RESTRICT3, "__restrict__")
4072 DEF(TOK_EXTENSION, "__extension__")
4073
4074 (TOK_FLOAT, "float")
4075 DEF(TOK_DOUBLE, "double")
4076 DEF(TOK_BOOL, "_Bool")
4077 DEF(TOK_SHORT, "short")
4078 DEF(TOK_STRUCT, "struct")
4079 DEF(TOK_UNION, "union")
4080 DEF(TOK_TYPEDEF, "typedef")
4081 DEF(TOK_DEFAULT, "default")
4082 DEF(TOK_ENUM, "enum")
4083 DEF(TOK_SIZEOF, "sizeof")
4084 DEF(TOK_ATTRIBUTE1, "__attribute")
4085 DEF(TOK_ATTRIBUTE2, "__attribute__")
4086 DEF(TOK_ALIGNOF1, "__alignof")
4087 DEF(TOK_ALIGNOF2, "__alignof__")
4088 DEF(TOK_TYPEOF1, "typeof")
4089 DEF(TOK_TYPEOF2, "__typeof")
4090 DEF(TOK_TYPEOF3, "__typeof__")
4091 DEF(TOK_LABEL, "__label__")
4092 DEF(TOK_ASM1, "asm")
4093 DEF(TOK_ASM2, "__asm")
4094 DEF(TOK_ASM3, "__asm__")
4095
4096
4097
4098
4099 (TOK_DEFINE, "define")
4100 DEF(TOK_INCLUDE, "include")
4101 DEF(TOK_INCLUDE_NEXT, "include_next")
4102 DEF(TOK_IFDEF, "ifdef")
4103 DEF(TOK_IFNDEF, "ifndef")
4104 DEF(TOK_ELIF, "elif")
4105 DEF(TOK_ENDIF, "endif")
4106 DEF(TOK_DEFINED, "defined")
4107 DEF(TOK_UNDEF, "undef")
4108 DEF(TOK_ERROR, "error")
4109 DEF(TOK_WARNING, "warning")
4110 DEF(TOK_LINE, "line")
4111 DEF(TOK_PRAGMA, "pragma")
4112 DEF(TOK___LINE__, "__LINE__")
4113 DEF(TOK___FILE__, "__FILE__")
4114 DEF(TOK___DATE__, "__DATE__")
4115 DEF(TOK___TIME__, "__TIME__")
4116 DEF(TOK___FUNCTION__, "__FUNCTION__")
4117 DEF(TOK___VA_ARGS__, "__VA_ARGS__")
4118
4119
4120 (TOK___FUNC__, "__func__")
4121
4122
4123
4124 (TOK_SECTION1, "section")
4125 DEF(TOK_SECTION2, "__section__")
4126 DEF(TOK_ALIGNED1, "aligned")
4127 DEF(TOK_ALIGNED2, "__aligned__")
4128 DEF(TOK_PACKED1, "packed")
4129 DEF(TOK_PACKED2, "__packed__")
4130 DEF(TOK_UNUSED1, "unused")
4131 DEF(TOK_UNUSED2, "__unused__")
4132 DEF(TOK_CDECL1, "cdecl")
4133 DEF(TOK_CDECL2, "__cdecl")
4134 DEF(TOK_CDECL3, "__cdecl__")
4135 DEF(TOK_STDCALL1, "stdcall")
4136 DEF(TOK_STDCALL2, "__stdcall")
4137 DEF(TOK_STDCALL3, "__stdcall__")
4138 DEF(TOK_DLLEXPORT, "dllexport")
4139 DEF(TOK_NORETURN1, "noreturn")
4140 DEF(TOK_NORETURN2, "__noreturn__")
4141 DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p")
4142 DEF(TOK_builtin_constant_p, "__builtin_constant_p")
4143 DEF(TOK_REGPARM1, "regparm")
4144 DEF(TOK_REGPARM2, "__regparm__")
4145
4146
4147 (TOK_pack, "pack")
4148 #if !defined(TCC_TARGET_I386)
4149
4150 (TOK_ASM_push, "push")
4151 DEF(TOK_ASM_pop, "pop")
4152 #endif
4153
4154
4155 (TOK_memcpy, "memcpy")
4156 DEF(TOK_memset, "memset")
4157 DEF(TOK_alloca, "alloca")
4158 DEF(TOK___divdi3, "__divdi3")
4159 DEF(TOK___moddi3, "__moddi3")
4160 DEF(TOK___udivdi3, "__udivdi3")
4161 DEF(TOK___umoddi3, "__umoddi3")
4162 #if defined(TCC_TARGET_ARM)
4163 DEF(TOK___divsi3, "__divsi3")
4164 DEF(TOK___modsi3, "__modsi3")
4165 DEF(TOK___udivsi3, "__udivsi3")
4166 DEF(TOK___umodsi3, "__umodsi3")
4167 DEF(TOK___sardi3, "__ashrdi3")
4168 DEF(TOK___shrdi3, "__lshrdi3")
4169 DEF(TOK___shldi3, "__ashldi3")
4170 DEF(TOK___slltold, "__slltold")
4171 DEF(TOK___fixunssfsi, "__fixunssfsi")
4172 DEF(TOK___fixunsdfsi, "__fixunsdfsi")
4173 DEF(TOK___fixunsxfsi, "__fixunsxfsi")
4174 DEF(TOK___fixsfdi, "__fixsfdi")
4175 DEF(TOK___fixdfdi, "__fixdfdi")
4176 DEF(TOK___fixxfdi, "__fixxfdi")
4177 #elif defined(TCC_TARGET_C67)
4178 DEF(TOK__divi, "_divi")
4179 DEF(TOK__divu, "_divu")
4180 DEF(TOK__divf, "_divf")
4181 DEF(TOK__divd, "_divd")
4182 DEF(TOK__remi, "_remi")
4183 DEF(TOK__remu, "_remu")
4184 DEF(TOK___sardi3, "__sardi3")
4185 DEF(TOK___shrdi3, "__shrdi3")
4186 DEF(TOK___shldi3, "__shldi3")
4187 #else
4188
4189 (TOK___sardi3, "__sardi3")
4190 DEF(TOK___shrdi3, "__shrdi3")
4191 DEF(TOK___shldi3, "__shldi3")
4192 #endif
4193 DEF(TOK___tcc_int_fpu_control, "__tcc_int_fpu_control")
4194 DEF(TOK___tcc_fpu_control, "__tcc_fpu_control")
4195 DEF(TOK___ulltof, "__ulltof")
4196 DEF(TOK___ulltod, "__ulltod")
4197 DEF(TOK___ulltold, "__ulltold")
4198 DEF(TOK___fixunssfdi, "__fixunssfdi")
4199 DEF(TOK___fixunsdfdi, "__fixunsdfdi")
4200 DEF(TOK___fixunsxfdi, "__fixunsxfdi")
4201 DEF(TOK___chkstk, "__chkstk")
4202
4203
4204 #ifdef CONFIG_TCC_BCHECK
4205 DEF(TOK___bound_ptr_add, "__bound_ptr_add")
4206 DEF(TOK___bound_ptr_indir1, "__bound_ptr_indir1")
4207 DEF(TOK___bound_ptr_indir2, "__bound_ptr_indir2")
4208 DEF(TOK___bound_ptr_indir4, "__bound_ptr_indir4")
4209 DEF(TOK___bound_ptr_indir8, "__bound_ptr_indir8")
4210 DEF(TOK___bound_ptr_indir12, "__bound_ptr_indir12")
4211 DEF(TOK___bound_ptr_indir16, "__bound_ptr_indir16")
4212 DEF(TOK___bound_local_new, "__bound_local_new")
4213 DEF(TOK___bound_local_delete, "__bound_local_delete")
4214 DEF(TOK_malloc, "malloc")
4215 DEF(TOK_free, "free")
4216 DEF(TOK_realloc, "realloc")
4217 DEF(TOK_memalign, "memalign")
4218 DEF(TOK_calloc, "calloc")
4219 DEF(TOK_memmove, "memmove")
4220 DEF(TOK_strlen, "strlen")
4221 DEF(TOK_strcpy, "strcpy")
4222 #endif
4223
4224
4225
4226 (byte)
4227 DEF_ASM(align)
4228 DEF_ASM(skip)
4229 DEF_ASM(space)
4230 DEF_ASM(string)
4231 DEF_ASM(asciz)
4232 DEF_ASM(ascii)
4233 DEF_ASM(globl)
4234 DEF_ASM(global)
4235 DEF_ASM(text)
4236 DEF_ASM(data)
4237 DEF_ASM(bss)
4238 DEF_ASM(previous)
4239 DEF_ASM(fill)
4240 DEF_ASM(org)
4241 DEF_ASM(quad)
4242
4243 #ifdef TCC_TARGET_I386
4244
4245
4246 (al)
4247 DEF_ASM(cl)
4248 DEF_ASM(dl)
4249 DEF_ASM(bl)
4250 DEF_ASM(ah)
4251 DEF_ASM(ch)
4252 DEF_ASM(dh)
4253 DEF_ASM(bh)
4254 DEF_ASM(ax)
4255 DEF_ASM(cx)
4256 DEF_ASM(dx)
4257 DEF_ASM(bx)
4258 DEF_ASM(sp)
4259 DEF_ASM(bp)
4260 DEF_ASM(si)
4261 DEF_ASM(di)
4262 DEF_ASM(eax)
4263 DEF_ASM(ecx)
4264 DEF_ASM(edx)
4265 DEF_ASM(ebx)
4266 DEF_ASM(esp)
4267 DEF_ASM(ebp)
4268 DEF_ASM(esi)
4269 DEF_ASM(edi)
4270 DEF_ASM(mm0)
4271 DEF_ASM(mm1)
4272 DEF_ASM(mm2)
4273 DEF_ASM(mm3)
4274 DEF_ASM(mm4)
4275 DEF_ASM(mm5)
4276 DEF_ASM(mm6)
4277 DEF_ASM(mm7)
4278 DEF_ASM(xmm0)
4279 DEF_ASM(xmm1)
4280 DEF_ASM(xmm2)
4281 DEF_ASM(xmm3)
4282 DEF_ASM(xmm4)
4283 DEF_ASM(xmm5)
4284 DEF_ASM(xmm6)
4285 DEF_ASM(xmm7)
4286 DEF_ASM(cr0)
4287 DEF_ASM(cr1)
4288 DEF_ASM(cr2)
4289 DEF_ASM(cr3)
4290 DEF_ASM(cr4)
4291 DEF_ASM(cr5)
4292 DEF_ASM(cr6)
4293 DEF_ASM(cr7)
4294 DEF_ASM(tr0)
4295 DEF_ASM(tr1)
4296 DEF_ASM(tr2)
4297 DEF_ASM(tr3)
4298 DEF_ASM(tr4)
4299 DEF_ASM(tr5)
4300 DEF_ASM(tr6)
4301 DEF_ASM(tr7)
4302 DEF_ASM(db0)
4303 DEF_ASM(db1)
4304 DEF_ASM(db2)
4305 DEF_ASM(db3)
4306 DEF_ASM(db4)
4307 DEF_ASM(db5)
4308 DEF_ASM(db6)
4309 DEF_ASM(db7)
4310 DEF_ASM(dr0)
4311 DEF_ASM(dr1)
4312 DEF_ASM(dr2)
4313 DEF_ASM(dr3)
4314 DEF_ASM(dr4)
4315 DEF_ASM(dr5)
4316 DEF_ASM(dr6)
4317 DEF_ASM(dr7)
4318 DEF_ASM(es)
4319 DEF_ASM(cs)
4320 DEF_ASM(ss)
4321 DEF_ASM(ds)
4322 DEF_ASM(fs)
4323 DEF_ASM(gs)
4324 DEF_ASM(st)
4325
4326 DEF_BWL(mov)
4327
4328
4329 (add)
4330 DEF_BWL(or)
4331 DEF_BWL(adc)
4332 DEF_BWL(sbb)
4333 DEF_BWL(and)
4334 DEF_BWL(sub)
4335 DEF_BWL(xor)
4336 DEF_BWL(cmp)
4337
4338
4339 (inc)
4340 DEF_BWL(dec)
4341 DEF_BWL(not)
4342 DEF_BWL(neg)
4343 DEF_BWL(mul)
4344 DEF_BWL(imul)
4345 DEF_BWL(div)
4346 DEF_BWL(idiv)
4347
4348 DEF_BWL(xchg)
4349 DEF_BWL(test)
4350
4351
4352 (rol)
4353 DEF_BWL(ror)
4354 DEF_BWL(rcl)
4355 DEF_BWL(rcr)
4356 DEF_BWL(shl)
4357 DEF_BWL(shr)
4358 DEF_BWL(sar)
4359
4360 DEF_ASM(shldw)
4361 DEF_ASM(shldl)
4362 DEF_ASM(shld)
4363 DEF_ASM(shrdw)
4364 DEF_ASM(shrdl)
4365 DEF_ASM(shrd)
4366
4367 DEF_ASM(pushw)
4368 DEF_ASM(pushl)
4369 DEF_ASM(push)
4370 DEF_ASM(popw)
4371 DEF_ASM(popl)
4372 DEF_ASM(pop)
4373 DEF_BWL(in)
4374 DEF_BWL(out)
4375
4376 DEF_WL(movzb)
4377
4378 DEF_ASM(movzwl)
4379 DEF_ASM(movsbw)
4380 DEF_ASM(movsbl)
4381 DEF_ASM(movswl)
4382
4383 DEF_WL(lea)
4384
4385 DEF_ASM(les)
4386 DEF_ASM(lds)
4387 DEF_ASM(lss)
4388 DEF_ASM(lfs)
4389 DEF_ASM(lgs)
4390
4391 DEF_ASM(call)
4392 DEF_ASM(jmp)
4393 DEF_ASM(lcall)
4394 DEF_ASM(ljmp)
4395
4396 DEF_ASMTEST(j)
4397
4398 DEF_ASMTEST(set)
4399 DEF_ASMTEST(cmov)
4400
4401 DEF_WL(bsf)
4402 DEF_WL(bsr)
4403 DEF_WL(bt)
4404 DEF_WL(bts)
4405 DEF_WL(btr)
4406 DEF_WL(btc)
4407
4408 DEF_WL(lsl)
4409
4410
4411 (add)
4412 DEF_FP(mul)
4413
4414 DEF_ASM(fcom)
4415 DEF_ASM(fcom_1)
4416 (com)
4417
4418 DEF_FP(comp)
4419 DEF_FP(sub)
4420 DEF_FP(subr)
4421 DEF_FP(div)
4422 DEF_FP(divr)
4423
4424 DEF_BWL(xadd)
4425 DEF_BWL(cmpxchg)
4426
4427
4428 (cmps)
4429 DEF_BWL(scmp)
4430 DEF_BWL(ins)
4431 DEF_BWL(outs)
4432 DEF_BWL(lods)
4433 DEF_BWL(slod)
4434 DEF_BWL(movs)
4435 DEF_BWL(smov)
4436 DEF_BWL(scas)
4437 DEF_BWL(ssca)
4438 DEF_BWL(stos)
4439 DEF_BWL(ssto)
4440
4441
4442
4443 #define ALT(x)
4444 #define DEF_ASM_OP0(name, opcode) DEF_ASM(name)
4445 #define DEF_ASM_OP0L(name, opcode, group, instr_type)
4446 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0)
4447 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1)
4448 #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2)
4449
4450
4451
4452 (pusha, 0x60)
4453 (popa, 0x61)
4454 DEF_ASM_OP0(clc, 0xf8)
4455 DEF_ASM_OP0(cld, 0xfc)
4456 DEF_ASM_OP0(cli, 0xfa)
4457 DEF_ASM_OP0(clts, 0x0f06)
4458 DEF_ASM_OP0(cmc, 0xf5)
4459 DEF_ASM_OP0(lahf, 0x9f)
4460 DEF_ASM_OP0(sahf, 0x9e)
4461 DEF_ASM_OP0(pushfl, 0x9c)
4462 DEF_ASM_OP0(popfl, 0x9d)
4463 DEF_ASM_OP0(pushf, 0x9c)
4464 DEF_ASM_OP0(popf, 0x9d)
4465 DEF_ASM_OP0(stc, 0xf9)
4466 DEF_ASM_OP0(std, 0xfd)
4467 DEF_ASM_OP0(sti, 0xfb)
4468 DEF_ASM_OP0(aaa, 0x37)
4469 DEF_ASM_OP0(aas, 0x3f)
4470 DEF_ASM_OP0(daa, 0x27)
4471 DEF_ASM_OP0(das, 0x2f)
4472 DEF_ASM_OP0(aad, 0xd50a)
4473 DEF_ASM_OP0(aam, 0xd40a)
4474 DEF_ASM_OP0(cbw, 0x6698)
4475 DEF_ASM_OP0(cwd, 0x6699)
4476 DEF_ASM_OP0(cwde, 0x98)
4477 DEF_ASM_OP0(cdq, 0x99)
4478 DEF_ASM_OP0(cbtw, 0x6698)
4479 DEF_ASM_OP0(cwtl, 0x98)
4480 DEF_ASM_OP0(cwtd, 0x6699)
4481 DEF_ASM_OP0(cltd, 0x99)
4482 DEF_ASM_OP0(int3, 0xcc)
4483 DEF_ASM_OP0(into, 0xce)
4484 DEF_ASM_OP0(iret, 0xcf)
4485 DEF_ASM_OP0(rsm, 0x0faa)
4486 DEF_ASM_OP0(hlt, 0xf4)
4487 DEF_ASM_OP0(wait, 0x9b)
4488 DEF_ASM_OP0(nop, 0x90)
4489 DEF_ASM_OP0(xlat, 0xd7)
4490
4491
4492 (DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
4493 ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
4494
4495 ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
4496 ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
4497
4498 ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
4499 ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
4500
4501 ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
4502 ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
4503
4504 ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
4505 ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
4506
4507 ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
4508 ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
4509
4510
4511
4512 (DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
4513 ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
4514
4515 ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4516 ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4517
4518 ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4519 ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4520
4521 ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4522 ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4523
4524 ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4525 ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4526
4527
4528 (aword, 0x67)
4529 DEF_ASM_OP0(addr16, 0x67)
4530 DEF_ASM_OP0(word, 0x66)
4531 DEF_ASM_OP0(data16, 0x66)
4532 DEF_ASM_OP0(lock, 0xf0)
4533 DEF_ASM_OP0(rep, 0xf3)
4534 DEF_ASM_OP0(repe, 0xf3)
4535 DEF_ASM_OP0(repz, 0xf3)
4536 DEF_ASM_OP0(repne, 0xf2)
4537 DEF_ASM_OP0(repnz, 0xf2)
4538
4539 DEF_ASM_OP0(invd, 0x0f08)
4540 DEF_ASM_OP0(wbinvd, 0x0f09)
4541 DEF_ASM_OP0(cpuid, 0x0fa2)
4542 DEF_ASM_OP0(wrmsr, 0x0f30)
4543 DEF_ASM_OP0(rdtsc, 0x0f31)
4544 DEF_ASM_OP0(rdmsr, 0x0f32)
4545 DEF_ASM_OP0(rdpmc, 0x0f33)
4546 DEF_ASM_OP0(ud2, 0x0f0b)
4547
4548
4549 (DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
4550 ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
4551 ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
4552 ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
4553 ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
4554 ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
4555
4556 ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
4557 ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
4558
4559 ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
4560 ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
4561 ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
4562 ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
4563 ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
4564 ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
4565
4566 ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
4567 ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
4568 ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
4569 ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
4570 ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
4571
4572 ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
4573 ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
4574 ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
4575 ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
4576 ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
4577
4578 ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
4579 ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
4580 ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
4581
4582 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
4583 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
4584 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
4585 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
4586
4587 ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
4588 ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
4589 ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
4590 ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
4591
4592 ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
4593 ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
4594 ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
4595 ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
4596
4597 ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
4598
4599 ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
4600 ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
4601 ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
4602 ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
4603 ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
4604
4605
4606 (DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
4607 (DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
4608 ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
4609 ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
4610 ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
4611
4612 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
4613 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
4614 ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
4615 ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
4616
4617 ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
4618 ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4619 ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
4620 ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4621
4622 ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4623 ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4624
4625 ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4626 ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4627
4628 ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
4629 ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
4630 ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
4631 ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
4632 ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
4633
4634 ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4635 ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
4636 ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4637 ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
4638
4639
4640 (DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
4641 ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
4642 ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
4643
4644 ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
4645 ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
4646 ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
4647 ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
4648 ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
4649 ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
4650
4651 ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
4652 ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
4653 ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
4654 ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
4655
4656 ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
4657 ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
4658 ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
4659 ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
4660
4661 ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
4662 ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
4663 DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
4664 DEF_ASM_OP0(leave, 0xc9)
4665 DEF_ASM_OP0(ret, 0xc3)
4666 ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
4667 DEF_ASM_OP0(lret, 0xcb)
4668 ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
4669
4670 ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
4671 DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
4672 DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
4673 DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
4674 DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
4675 DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
4676 DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
4677
4678
4679
4680 (DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
4681
4682 ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
4683 ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
4684 ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
4685 ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
4686 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
4687 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
4688 ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
4689 ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
4690 ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
4691 ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
4692 ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
4693
4694 DEF_ASM_OP0(fucompp, 0xdae9)
4695 DEF_ASM_OP0(ftst, 0xd9e4)
4696 DEF_ASM_OP0(fxam, 0xd9e5)
4697 DEF_ASM_OP0(fld1, 0xd9e8)
4698 DEF_ASM_OP0(fldl2t, 0xd9e9)
4699 DEF_ASM_OP0(fldl2e, 0xd9ea)
4700 DEF_ASM_OP0(fldpi, 0xd9eb)
4701 DEF_ASM_OP0(fldlg2, 0xd9ec)
4702 DEF_ASM_OP0(fldln2, 0xd9ed)
4703 DEF_ASM_OP0(fldz, 0xd9ee)
4704
4705 DEF_ASM_OP0(f2xm1, 0xd9f0)
4706 DEF_ASM_OP0(fyl2x, 0xd9f1)
4707 DEF_ASM_OP0(fptan, 0xd9f2)
4708 DEF_ASM_OP0(fpatan, 0xd9f3)
4709 DEF_ASM_OP0(fxtract, 0xd9f4)
4710 DEF_ASM_OP0(fprem1, 0xd9f5)
4711 DEF_ASM_OP0(fdecstp, 0xd9f6)
4712 DEF_ASM_OP0(fincstp, 0xd9f7)
4713 DEF_ASM_OP0(fprem, 0xd9f8)
4714 DEF_ASM_OP0(fyl2xp1, 0xd9f9)
4715 DEF_ASM_OP0(fsqrt, 0xd9fa)
4716 DEF_ASM_OP0(fsincos, 0xd9fb)
4717 DEF_ASM_OP0(frndint, 0xd9fc)
4718 DEF_ASM_OP0(fscale, 0xd9fd)
4719 DEF_ASM_OP0(fsin, 0xd9fe)
4720 DEF_ASM_OP0(fcos, 0xd9ff)
4721 DEF_ASM_OP0(fchs, 0xd9e0)
4722 DEF_ASM_OP0(fabs, 0xd9e1)
4723 DEF_ASM_OP0(fninit, 0xdbe3)
4724 DEF_ASM_OP0(fnclex, 0xdbe2)
4725 DEF_ASM_OP0(fnop, 0xd9d0)
4726 DEF_ASM_OP0(fwait, 0x9b)
4727
4728
4729 (fld, 0xd9c0, 0, OPC_REG, OPT_ST)
4730 DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
4731 DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
4732 ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
4733 DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
4734 DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
4735 DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
4736 DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
4737 DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
4738
4739
4740 (fst, 0xddd0, 0, OPC_REG, OPT_ST)
4741 DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
4742 DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
4743 DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
4744 ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
4745 DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
4746 DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
4747 DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
4748 DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
4749 DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
4750
4751 DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
4752 DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
4753 DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
4754 DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
4755 DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
4756
4757
4758 (fxch, 0xd9c9)
4759 ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
4760
4761
4762 (fucom, 0xdde0, 0, OPC_REG, OPT_ST )
4763 DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
4764
4765 DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
4766 DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
4767 DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
4768 DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
4769 DEF_ASM_OP0(fnstsw, 0xdfe0)
4770 ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
4771 ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
4772 DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
4773 ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
4774 ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
4775 DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
4776 DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
4777 DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
4778 DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
4779 DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
4780 DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
4781 DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
4782 DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
4783 DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
4784 DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
4785 DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
4786
4787
4788 (arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
4789 DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
4790 DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
4791 DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
4792 DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
4793 DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
4794 ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
4795 DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
4796 DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
4797 DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
4798 DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
4799 DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
4800 DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
4801 DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
4802 DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
4803
4804
4805 (bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
4806 ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
4807 ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
4808 DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
4809
4810 DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
4811 DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
4812
4813
4814 (cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
4815
4816
4817 (DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
4818
4819 DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
4820 DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
4821 DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
4822 DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
4823 DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
4824 DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
4825 DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
4826 DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
4827
4828 DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
4829 DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
4830 DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
4831 DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
4832
4833
4834 (emms, 0x0f77)
4835 (movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
4836 ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
4837 DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4838 ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
4839 DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4840 DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4841 DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4842 DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4843 DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4844 DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4845 DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4846 DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4847 DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4848 DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4849 DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4850 DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4851 DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4852 DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4853 DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4854 DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4855 DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4856 DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4857 DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4858 DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4859 DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4860 DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4861 DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4862 ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
4863 DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4864 ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
4865 DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4866 ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
4867 DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4868 ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
4869 DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4870 ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
4871 DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4872 ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
4873 DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4874 ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
4875 DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4876 ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
4877 DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4878 DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4879 DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4880 DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4881 DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4882 DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4883 DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4884 DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4885 DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4886 DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4887 DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4888 DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4889 DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4890 DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4891
4892 #undef ALT
4893 #undef DEF_ASM_OP0
4894 #undef DEF_ASM_OP0L
4895 #undef DEF_ASM_OP1
4896 #undef DEF_ASM_OP2
4897 #undef DEF_ASM_OP3
4898
4899
4900 #define ALT(x)
4901 #define DEF_ASM_OP0(name, opcode)
4902 #define DEF_ASM_OP0L(name, opcode, group, instr_type) DEF_ASM(name)
4903 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0) DEF_ASM(name)
4904 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) DEF_ASM(name)
4905 #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) DEF_ASM(name)
4906
4907
4908
4909 (pusha, 0x60)
4910 (popa, 0x61)
4911 DEF_ASM_OP0(clc, 0xf8)
4912 DEF_ASM_OP0(cld, 0xfc)
4913 DEF_ASM_OP0(cli, 0xfa)
4914 DEF_ASM_OP0(clts, 0x0f06)
4915 DEF_ASM_OP0(cmc, 0xf5)
4916 DEF_ASM_OP0(lahf, 0x9f)
4917 DEF_ASM_OP0(sahf, 0x9e)
4918 DEF_ASM_OP0(pushfl, 0x9c)
4919 DEF_ASM_OP0(popfl, 0x9d)
4920 DEF_ASM_OP0(pushf, 0x9c)
4921 DEF_ASM_OP0(popf, 0x9d)
4922 DEF_ASM_OP0(stc, 0xf9)
4923 DEF_ASM_OP0(std, 0xfd)
4924 DEF_ASM_OP0(sti, 0xfb)
4925 DEF_ASM_OP0(aaa, 0x37)
4926 DEF_ASM_OP0(aas, 0x3f)
4927 DEF_ASM_OP0(daa, 0x27)
4928 DEF_ASM_OP0(das, 0x2f)
4929 DEF_ASM_OP0(aad, 0xd50a)
4930 DEF_ASM_OP0(aam, 0xd40a)
4931 DEF_ASM_OP0(cbw, 0x6698)
4932 DEF_ASM_OP0(cwd, 0x6699)
4933 DEF_ASM_OP0(cwde, 0x98)
4934 DEF_ASM_OP0(cdq, 0x99)
4935 DEF_ASM_OP0(cbtw, 0x6698)
4936 DEF_ASM_OP0(cwtl, 0x98)
4937 DEF_ASM_OP0(cwtd, 0x6699)
4938 DEF_ASM_OP0(cltd, 0x99)
4939 DEF_ASM_OP0(int3, 0xcc)
4940 DEF_ASM_OP0(into, 0xce)
4941 DEF_ASM_OP0(iret, 0xcf)
4942 DEF_ASM_OP0(rsm, 0x0faa)
4943 DEF_ASM_OP0(hlt, 0xf4)
4944 DEF_ASM_OP0(wait, 0x9b)
4945 DEF_ASM_OP0(nop, 0x90)
4946 DEF_ASM_OP0(xlat, 0xd7)
4947
4948
4949 (DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
4950 ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
4951
4952 ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
4953 ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
4954
4955 ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
4956 ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
4957
4958 ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
4959 ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
4960
4961 ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
4962 ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
4963
4964 ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
4965 ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
4966
4967
4968
4969 (DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
4970 ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
4971
4972 ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4973 ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4974
4975 ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4976 ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4977
4978 ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4979 ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4980
4981 ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4982 ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4983
4984
4985 (aword, 0x67)
4986 DEF_ASM_OP0(addr16, 0x67)
4987 DEF_ASM_OP0(word, 0x66)
4988 DEF_ASM_OP0(data16, 0x66)
4989 DEF_ASM_OP0(lock, 0xf0)
4990 DEF_ASM_OP0(rep, 0xf3)
4991 DEF_ASM_OP0(repe, 0xf3)
4992 DEF_ASM_OP0(repz, 0xf3)
4993 DEF_ASM_OP0(repne, 0xf2)
4994 DEF_ASM_OP0(repnz, 0xf2)
4995
4996 DEF_ASM_OP0(invd, 0x0f08)
4997 DEF_ASM_OP0(wbinvd, 0x0f09)
4998 DEF_ASM_OP0(cpuid, 0x0fa2)
4999 DEF_ASM_OP0(wrmsr, 0x0f30)
5000 DEF_ASM_OP0(rdtsc, 0x0f31)
5001 DEF_ASM_OP0(rdmsr, 0x0f32)
5002 DEF_ASM_OP0(rdpmc, 0x0f33)
5003 DEF_ASM_OP0(ud2, 0x0f0b)
5004
5005
5006 (DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
5007 ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
5008 ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
5009 ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
5010 ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
5011 ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
5012
5013 ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
5014 ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
5015
5016 ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
5017 ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
5018 ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
5019 ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
5020 ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
5021 ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
5022
5023 ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
5024 ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
5025 ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
5026 ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
5027 ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
5028
5029 ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
5030 ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
5031 ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
5032 ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
5033 ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
5034
5035 ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
5036 ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
5037 ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
5038
5039 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
5040 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
5041 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
5042 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
5043
5044 ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
5045 ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
5046 ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
5047 ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
5048
5049 ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
5050 ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
5051 ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
5052 ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
5053
5054 ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
5055
5056 ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
5057 ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
5058 ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
5059 ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
5060 ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
5061
5062
5063 (DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
5064 (DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
5065 ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
5066 ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
5067 ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
5068
5069 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
5070 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
5071 ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
5072 ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
5073
5074 ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
5075 ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5076 ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
5077 ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5078
5079 ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5080 ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5081
5082 ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5083 ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5084
5085 ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
5086 ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
5087 ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
5088 ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
5089 ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
5090
5091 ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5092 ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
5093 ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5094 ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
5095
5096
5097 (DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
5098 ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
5099 ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
5100
5101 ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
5102 ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
5103 ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
5104 ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
5105 ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
5106 ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
5107
5108 ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
5109 ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
5110 ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
5111 ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
5112
5113 ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
5114 ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
5115 ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
5116 ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
5117
5118 ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
5119 ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
5120 DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
5121 DEF_ASM_OP0(leave, 0xc9)
5122 DEF_ASM_OP0(ret, 0xc3)
5123 ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
5124 DEF_ASM_OP0(lret, 0xcb)
5125 ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
5126
5127 ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
5128 DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
5129 DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
5130 DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
5131 DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
5132 DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
5133 DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
5134
5135
5136
5137 (DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
5138
5139 ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
5140 ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
5141 ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
5142 ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
5143 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
5144 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
5145 ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
5146 ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
5147 ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
5148 ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
5149 ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
5150
5151 DEF_ASM_OP0(fucompp, 0xdae9)
5152 DEF_ASM_OP0(ftst, 0xd9e4)
5153 DEF_ASM_OP0(fxam, 0xd9e5)
5154 DEF_ASM_OP0(fld1, 0xd9e8)
5155 DEF_ASM_OP0(fldl2t, 0xd9e9)
5156 DEF_ASM_OP0(fldl2e, 0xd9ea)
5157 DEF_ASM_OP0(fldpi, 0xd9eb)
5158 DEF_ASM_OP0(fldlg2, 0xd9ec)
5159 DEF_ASM_OP0(fldln2, 0xd9ed)
5160 DEF_ASM_OP0(fldz, 0xd9ee)
5161
5162 DEF_ASM_OP0(f2xm1, 0xd9f0)
5163 DEF_ASM_OP0(fyl2x, 0xd9f1)
5164 DEF_ASM_OP0(fptan, 0xd9f2)
5165 DEF_ASM_OP0(fpatan, 0xd9f3)
5166 DEF_ASM_OP0(fxtract, 0xd9f4)
5167 DEF_ASM_OP0(fprem1, 0xd9f5)
5168 DEF_ASM_OP0(fdecstp, 0xd9f6)
5169 DEF_ASM_OP0(fincstp, 0xd9f7)
5170 DEF_ASM_OP0(fprem, 0xd9f8)
5171 DEF_ASM_OP0(fyl2xp1, 0xd9f9)
5172 DEF_ASM_OP0(fsqrt, 0xd9fa)
5173 DEF_ASM_OP0(fsincos, 0xd9fb)
5174 DEF_ASM_OP0(frndint, 0xd9fc)
5175 DEF_ASM_OP0(fscale, 0xd9fd)
5176 DEF_ASM_OP0(fsin, 0xd9fe)
5177 DEF_ASM_OP0(fcos, 0xd9ff)
5178 DEF_ASM_OP0(fchs, 0xd9e0)
5179 DEF_ASM_OP0(fabs, 0xd9e1)
5180 DEF_ASM_OP0(fninit, 0xdbe3)
5181 DEF_ASM_OP0(fnclex, 0xdbe2)
5182 DEF_ASM_OP0(fnop, 0xd9d0)
5183 DEF_ASM_OP0(fwait, 0x9b)
5184
5185
5186 (fld, 0xd9c0, 0, OPC_REG, OPT_ST)
5187 DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
5188 DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
5189 ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
5190 DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
5191 DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
5192 DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
5193 DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
5194 DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
5195
5196
5197 (fst, 0xddd0, 0, OPC_REG, OPT_ST)
5198 DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
5199 DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
5200 DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
5201 ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
5202 DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
5203 DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
5204 DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
5205 DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
5206 DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
5207
5208 DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
5209 DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
5210 DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
5211 DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
5212 DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
5213
5214
5215 (fxch, 0xd9c9)
5216 ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
5217
5218
5219 (fucom, 0xdde0, 0, OPC_REG, OPT_ST )
5220 DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
5221
5222 DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
5223 DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
5224 DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
5225 DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
5226 DEF_ASM_OP0(fnstsw, 0xdfe0)
5227 ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
5228 ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
5229 DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
5230 ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
5231 ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
5232 DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
5233 DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
5234 DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
5235 DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
5236 DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
5237 DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
5238 DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
5239 DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
5240 DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
5241 DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
5242 DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
5243
5244
5245 (arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
5246 DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
5247 DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
5248 DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
5249 DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
5250 DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
5251 ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
5252 DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
5253 DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
5254 DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
5255 DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
5256 DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
5257 DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
5258 DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
5259 DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
5260
5261
5262 (bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
5263 ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
5264 ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
5265 DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
5266
5267 DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
5268 DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
5269
5270
5271 (cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
5272
5273
5274 (DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
5275
5276 DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
5277 DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
5278 DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
5279 DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
5280 DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
5281 DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
5282 DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
5283 DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
5284
5285 DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
5286 DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
5287 DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
5288 DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
5289
5290
5291 (emms, 0x0f77)
5292 (movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
5293 ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
5294 DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5295 ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
5296 DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5297 DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5298 DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5299 DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5300 DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5301 DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5302 DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5303 DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5304 DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5305 DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5306 DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5307 DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5308 DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5309 DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5310 DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5311 DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5312 DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5313 DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5314 DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5315 DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5316 DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5317 DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5318 DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5319 ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
5320 DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5321 ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
5322 DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5323 ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
5324 DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5325 ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
5326 DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5327 ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
5328 DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5329 ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
5330 DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5331 ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
5332 DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5333 ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
5334 DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5335 DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5336 DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5337 DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5338 DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5339 DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5340 DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5341 DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5342 DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5343 DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5344 DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5345 DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5346 DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5347 DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5348
5349 #undef ALT
5350 #undef DEF_ASM_OP0
5351 #undef DEF_ASM_OP0L
5352 #undef DEF_ASM_OP1
5353 #undef DEF_ASM_OP2
5354 #undef DEF_ASM_OP3
5355
5356
5357 #endif
5358
5359 #undef DEF
5360 ;
5361
5362 #define TOK_UIDENT TOK_DEFINE
5363
5364 #ifdef WIN32
5365 int __stdcall GetModuleFileNameA(void *, char *, int);
5366 void *__stdcall GetProcAddress(void *, const char *);
5367 void *__stdcall GetModuleHandleA(const char *);
5368 void *__stdcall LoadLibraryA(const char *);
5369 int __stdcall FreeConsole(void);
5370
5371 #define snprintf _snprintf
5372 #define vsnprintf _vsnprintf
5373 #ifndef __GNUC__
5374 #define strtold (long double)strtod
5375 #define strtof (float)strtod
5376 #define strtoll (long long)strtol
5377 #endif
5378 #elif defined(TCC_UCLIBC) || defined(__FreeBSD__)
5379
5380 long double strtold(const char *nptr, char **endptr)
5381 {
5382 return (long double)strtod(nptr, endptr);
5383 }
5384 float strtof(const char *nptr, char **endptr)
5385 {
5386 return (float)strtod(nptr, endptr);
5387 }
5388 #else
5389
5390 extern float strtof (const char *__nptr, char **__endptr);
5391 extern long double strtold (const char *__nptr, char **__endptr);
5392 #endif
5393
5394 static char *pstrcpy(char *buf, int buf_size, const char *s);
5395 static char *pstrcat(char *buf, int buf_size, const char *s);
5396 static const char *tcc_basename(const char *name);
5397
5398 static void next(void);
5399 static void next_nomacro(void);
5400 static void parse_expr_type(CType *type);
5401 static void expr_type(CType *type);
5402 static void unary_type(CType *type);
5403 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
5404 int case_reg, int is_expr);
5405 static int expr_const(void);
5406 static void expr_eq(void);
5407 static void gexpr(void);
5408 static void gen_inline_functions(void);
5409 static void decl(int l);
5410 static void decl_initializer(CType *type, Section *sec, unsigned long c,
5411 int first, int size_only);
5412 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
5413 int has_init, int v, int scope);
5414 int gv(int rc);
5415 void gv2(int rc1, int rc2);
5416 void move_reg(int r, int s);
5417 void save_regs(int n);
5418 void save_reg(int r);
5419 void vpop(void);
5420 void vswap(void);
5421 void vdup(void);
5422 int get_reg(int rc);
5423 int get_reg_ex(int rc,int rc2);
5424
5425 struct macro_level {
5426 struct macro_level *prev;
5427 int *p;
5428 };
5429
5430 static void macro_subst(TokenString *tok_str, Sym **nested_list,
5431 const int *macro_str, struct macro_level **can_read_stream);
5432 void gen_op(int op);
5433 void force_charshort_cast(int t);
5434 static void gen_cast(CType *type);
5435 void vstore(void);
5436 static Sym *sym_find(int v);
5437 static Sym *sym_push(int v, CType *type, int r, int c);
5438
5439
5440 static int type_size(CType *type, int *a);
5441 static inline CType *pointed_type(CType *type);
5442 static int pointed_size(CType *type);
5443 static int lvalue_type(int t);
5444 static int parse_btype(CType *type, AttributeDef *ad);
5445 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
5446 static int is_compatible_types(CType *type1, CType *type2);
5447
5448 int ieee_finite(double d);
5449 void error(const char *fmt, ...);
5450 void vpushi(int v);
5451 void vrott(int n);
5452 void vnrott(int n);
5453 void lexpand_nr(void);
5454 static void vpush_global_sym(CType *type, int v);
5455 void vset(CType *type, int r, int v);
5456 void type_to_str(char *buf, int buf_size,
5457 CType *type, const char *varstr);
5458 char *get_tok_str(int v, CValue *cv);
5459 static Sym *get_sym_ref(CType *type, Section *sec,
5460 unsigned long offset, unsigned long size);
5461 static Sym *external_global_sym(int v, CType *type, int r);
5462
5463
5464 static void section_realloc(Section *sec, unsigned long new_size);
5465 static void *section_ptr_add(Section *sec, unsigned long size);
5466 static void put_extern_sym(Sym *sym, Section *section,
5467 unsigned long value, unsigned long size);
5468 static void greloc(Section *s, Sym *sym, unsigned long addr, int type);
5469 static int put_elf_str(Section *s, const char *sym);
5470 static int put_elf_sym(Section *s,
5471 unsigned long value, unsigned long size,
5472 int info, int other, int shndx, const char *name);
5473 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
5474 int info, int other, int sh_num, const char *name);
5475 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
5476 int type, int symbol);
5477 static void put_stabs(const char *str, int type, int other, int desc,
5478 unsigned long value);
5479 static void put_stabs_r(const char *str, int type, int other, int desc,
5480 unsigned long value, Section *sec, int sym_index);
5481 static void put_stabn(int type, int other, int desc, int value);
5482 static void put_stabd(int type, int other, int desc);
5483 static int tcc_add_dll(TCCState *s, const char *filename, int flags);
5484
5485 #define AFF_PRINT_ERROR 0x0001
5486 #define AFF_REFERENCED_DLL 0x0002
5487 static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
5488
5489
5490 int tcc_output_coff(TCCState *s1, FILE *f);
5491
5492
5493 void *resolve_sym(TCCState *s1, const char *sym, int type);
5494 int pe_load_def_file(struct TCCState *s1, FILE *fp);
5495 void pe_setup_paths(struct TCCState *s1, int *p_output_type, const char **p_outfile, char *first_file);
5496 unsigned long pe_add_runtime(struct TCCState *s1);
5497 int tcc_output_pe(struct TCCState *s1, const char *filename);
5498
5499
5500
5501 #ifdef CONFIG_TCC_ASM
5502
5503 typedef struct ExprValue {
5504 uint32_t v;
5505 Sym *sym;
5506 } ExprValue;
5507
5508 #define MAX_ASM_OPERANDS 30
5509
5510 typedef struct ASMOperand {
5511 int id;
5512 char *constraint;
5513 char asm_str[16];
5514 *vt;
5515 int ref_index;
5516 int input_index;
5517 int priority;
5518 int reg;
5519 int is_llong;
5520 int is_memory;
5521 int is_rw;
5522 } ASMOperand;
5523
5524 static void asm_expr(TCCState *s1, ExprValue *pe);
5525 static int asm_int_expr(TCCState *s1);
5526 static int find_constraint(ASMOperand *operands, int nb_operands,
5527 const char *name, const char **pp);
5528
5529 static int tcc_assemble(TCCState *s1, int do_preprocess);
5530
5531 #endif
5532
5533 static void asm_instr(void);
5534 static void asm_global_instr(void);
5535
5536
5537 static inline int is_float(int t)
5538 {
5539 int bt;
5540 bt = t & VT_BTYPE;
5541 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
5542 }
5543
5544 #ifdef TCC_TARGET_I386
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569 #define NB_REGS 4
5570
5571
5572
5573
5574 #define RC_INT 0x0001
5575 #define RC_FLOAT 0x0002
5576 #define RC_EAX 0x0004
5577 #define RC_ST0 0x0008
5578 #define RC_ECX 0x0010
5579 #define RC_EDX 0x0020
5580 #define RC_IRET RC_EAX
5581 #define RC_LRET RC_EDX
5582 #define RC_FRET RC_ST0
5583
5584
5585 enum {
5586 TREG_EAX = 0,
5587 TREG_ECX,
5588 TREG_EDX,
5589 TREG_ST0,
5590 };
5591
5592 int reg_classes[NB_REGS] = {
5593 | RC_EAX,
5594 | RC_ECX,
5595 | RC_EDX,
5596 | RC_ST0,
5597 };
5598
5599
5600 #define REG_IRET TREG_EAX
5601 #define REG_LRET TREG_EDX
5602 #define REG_FRET TREG_ST0
5603
5604
5605 #define INVERT_FUNC_PARAMS
5606
5607
5608
5609
5610
5611
5612 #define PTR_SIZE 4
5613
5614
5615 #define LDOUBLE_SIZE 12
5616 #define LDOUBLE_ALIGN 4
5617
5618 #define MAX_ALIGN 8
5619
5620
5621
5622
5623 #define EM_TCC_TARGET EM_386
5624
5625
5626 #define R_DATA_32 R_386_32
5627 #define R_JMP_SLOT R_386_JMP_SLOT
5628 #define R_COPY R_386_COPY
5629
5630 #define ELF_START_ADDR 0x08048000
5631 #define ELF_PAGE_SIZE 0x1000
5632
5633
5634
5635 static unsigned long func_sub_sp_offset;
5636 static unsigned long func_bound_offset;
5637 static int func_ret_sub;
5638
5639
5640 void g(int c)
5641 {
5642 int ind1;
5643 ind1 = ind + 1;
5644 if (ind1 > cur_text_section->data_allocated)
5645 section_realloc(cur_text_section, ind1);
5646 cur_text_section->data[ind] = c;
5647 ind = ind1;
5648 }
5649
5650 void o(unsigned int c)
5651 {
5652 while (c) {
5653 g(c);
5654 c = c >> 8;
5655 }
5656 }
5657
5658 void gen_le32(int c)
5659 {
5660 g(c);
5661 g(c >> 8);
5662 g(c >> 16);
5663 g(c >> 24);
5664 }
5665
5666
5667 void gsym_addr(int t, int a)
5668 {
5669 int n, *ptr;
5670 while (t) {
5671 ptr = (int *)(cur_text_section->data + t);
5672 n = *ptr;
5673 *ptr = a - t - 4;
5674 t = n;
5675 }
5676 }
5677
5678 void gsym(int t)
5679 {
5680 gsym_addr(t, ind);
5681 }
5682
5683
5684
5685 #define psym oad
5686
5687
5688 static int oad(int c, int s)
5689 {
5690 int ind1;
5691
5692 o(c);
5693 ind1 = ind + 4;
5694 if (ind1 > cur_text_section->data_allocated)
5695 section_realloc(cur_text_section, ind1);
5696 *(int *)(cur_text_section->data + ind) = s;
5697 s = ind;
5698 ind = ind1;
5699 return s;
5700 }
5701
5702
5703 static void gen_addr32(int r, Sym *sym, int c)
5704 {
5705 if (r & VT_SYM)
5706 greloc(cur_text_section, sym, ind, R_386_32);
5707 gen_le32(c);
5708 }
5709
5710
5711
5712 static void gen_modrm(int op_reg, int r, Sym *sym, int c)
5713 {
5714 op_reg = op_reg << 3;
5715 if ((r & VT_VALMASK) == VT_CONST) {
5716
5717 (0x05 | op_reg);
5718 gen_addr32(r, sym, c);
5719 } else if ((r & VT_VALMASK) == VT_LOCAL) {
5720
5721 if (c == (char)c) {
5722
5723 (0x45 | op_reg);
5724 g(c);
5725 } else {
5726 oad(0x85 | op_reg, c);
5727 }
5728 } else {
5729 g(0x00 | op_reg | (r & VT_VALMASK));
5730 }
5731 }
5732
5733
5734
5735 void load(int r, SValue *sv)
5736 {
5737 int v, t, ft, fc, fr;
5738 SValue v1;
5739
5740 fr = sv->r;
5741 ft = sv->type.t;
5742 fc = sv->c.ul;
5743
5744 v = fr & VT_VALMASK;
5745 if (fr & VT_LVAL) {
5746 if (v == VT_LLOCAL) {
5747 v1.type.t = VT_INT;
5748 v1.r = VT_LOCAL | VT_LVAL;
5749 v1.c.ul = fc;
5750 load(r, &v1);
5751 fr = r;
5752 }
5753 if ((ft & VT_BTYPE) == VT_FLOAT) {
5754 o(0xd9);
5755 = 0;
5756 } else if ((ft & VT_BTYPE) == VT_DOUBLE) {
5757 o(0xdd);
5758 = 0;
5759 } else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
5760 o(0xdb);
5761 = 5;
5762 } else if ((ft & VT_TYPE) == VT_BYTE) {
5763 o(0xbe0f);
5764 } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
5765 o(0xb60f);
5766 } else if ((ft & VT_TYPE) == VT_SHORT) {
5767 o(0xbf0f);
5768 } else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) {
5769 o(0xb70f);
5770 } else {
5771 o(0x8b);
5772 }
5773 gen_modrm(r, fr, sv->sym, fc);
5774 } else {
5775 if (v == VT_CONST) {
5776 o(0xb8 + r);
5777 (fr, sv->sym, fc);
5778 } else if (v == VT_LOCAL) {
5779 o(0x8d);
5780 (r, VT_LOCAL, sv->sym, fc);
5781 } else if (v == VT_CMP) {
5782 oad(0xb8 + r, 0);
5783 (0x0f);
5784 (fc);
5785 o(0xc0 + r);
5786 } else if (v == VT_JMP || v == VT_JMPI) {
5787 t = v & 1;
5788 oad(0xb8 + r, t);
5789 (0x05eb);
5790 (fc);
5791 oad(0xb8 + r, t ^ 1);
5792 } else if (v != r) {
5793 o(0x89);
5794 o(0xc0 + r + v * 8);
5795 }
5796 }
5797 }
5798
5799
5800 void store(int r, SValue *v)
5801 {
5802 int fr, bt, ft, fc;
5803
5804 ft = v->type.t;
5805 fc = v->c.ul;
5806 fr = v->r & VT_VALMASK;
5807 bt = ft & VT_BTYPE;
5808
5809 if (bt == VT_FLOAT) {
5810 o(0xd9);
5811 = 2;
5812 } else if (bt == VT_DOUBLE) {
5813 o(0xdd);
5814 = 2;
5815 } else if (bt == VT_LDOUBLE) {
5816 o(0xc0d9);
5817 (0xdb);
5818 = 7;
5819 } else {
5820 if (bt == VT_SHORT)
5821 o(0x66);
5822 if (bt == VT_BYTE || bt == VT_BOOL)
5823 o(0x88);
5824 else
5825 o(0x89);
5826 }
5827 if (fr == VT_CONST ||
5828 fr == VT_LOCAL ||
5829 (v->r & VT_LVAL)) {
5830 gen_modrm(r, v->r, v->sym, fc);
5831 } else if (fr != r) {
5832 o(0xc0 + fr + r * 8);
5833 }
5834 }
5835
5836 static void gadd_sp(int val)
5837 {
5838 if (val == (char)val) {
5839 o(0xc483);
5840 g(val);
5841 } else {
5842 oad(0xc481, val);
5843 }
5844 }
5845
5846
5847 static void gcall_or_jmp(int is_jmp)
5848 {
5849 int r;
5850 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
5851
5852 if (vtop->r & VT_SYM) {
5853
5854 (cur_text_section, vtop->sym,
5855 ind + 1, R_386_PC32);
5856 } else {
5857
5858 (symtab_section, cur_text_section,
5859 ind + 1, R_386_PC32, 0);
5860 }
5861 oad(0xe8 + is_jmp, vtop->c.ul - 4);
5862 } else {
5863
5864 = gv(RC_INT);
5865 o(0xff);
5866 (0xd0 + r + (is_jmp << 4));
5867 }
5868 }
5869
5870 static uint8_t fastcall_regs[3] = { TREG_EAX, TREG_EDX, TREG_ECX };
5871
5872
5873
5874
5875 void gfunc_call(int nb_args)
5876 {
5877 int size, align, r, args_size, i, func_call;
5878 Sym *func_sym;
5879
5880 args_size = 0;
5881 for(i = 0;i < nb_args; i++) {
5882 if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
5883 size = type_size(&vtop->type, &align);
5884
5885 = (size + 3) & ~3;
5886
5887 (0xec81, size);
5888
5889 = get_reg(RC_INT);
5890 o(0x89);
5891 (0xe0 + r);
5892 vset(&vtop->type, r | VT_LVAL, 0);
5893 vswap();
5894 vstore();
5895 args_size += size;
5896 } else if (is_float(vtop->type.t)) {
5897 gv(RC_FLOAT);
5898 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT)
5899 size = 4;
5900 else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
5901 size = 8;
5902 else
5903 size = 12;
5904 oad(0xec81, size);
5905 if (size == 12)
5906 o(0x7cdb);
5907 else
5908 o(0x5cd9 + size - 4);
5909 (0x24);
5910 g(0x00);
5911 args_size += size;
5912 } else {
5913
5914
5915 = gv(RC_INT);
5916 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
5917 size = 8;
5918 o(0x50 + vtop->r2);
5919 } else {
5920 size = 4;
5921 }
5922 o(0x50 + r);
5923 += size;
5924 }
5925 vtop--;
5926 }
5927 save_regs(0);
5928 = vtop->type.ref;
5929 func_call = func_sym->r;
5930
5931 if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
5932 int fastcall_nb_regs;
5933 fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
5934 for(i = 0;i < fastcall_nb_regs; i++) {
5935 if (args_size <= 0)
5936 break;
5937 o(0x58 + fastcall_regs[i]);
5938
5939 -= 4;
5940 }
5941 }
5942 gcall_or_jmp(0);
5943 if (args_size && func_sym->r != FUNC_STDCALL)
5944 gadd_sp(args_size);
5945 vtop--;
5946 }
5947
5948 #ifdef TCC_TARGET_PE
5949 #define FUNC_PROLOG_SIZE 10
5950 #else
5951 #define FUNC_PROLOG_SIZE 9
5952 #endif
5953
5954
5955 void gfunc_prolog(CType *func_type)
5956 {
5957 int addr, align, size, func_call, fastcall_nb_regs;
5958 int param_index, param_addr;
5959 Sym *sym;
5960 CType *type;
5961
5962 sym = func_type->ref;
5963 func_call = sym->r;
5964 addr = 8;
5965 loc = 0;
5966 if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
5967 fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
5968 } else {
5969 fastcall_nb_regs = 0;
5970 }
5971 param_index = 0;
5972
5973 ind += FUNC_PROLOG_SIZE;
5974 func_sub_sp_offset = ind;
5975
5976
5977 = sym->type;
5978 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
5979
5980 = addr;
5981 addr += 4;
5982 param_index++;
5983 }
5984
5985 while ((sym = sym->next) != NULL) {
5986 type = &sym->type;
5987 size = type_size(type, &align);
5988 size = (size + 3) & ~3;
5989 #ifdef FUNC_STRUCT_PARAM_AS_PTR
5990
5991 if ((type->t & VT_BTYPE) == VT_STRUCT) {
5992 size = 4;
5993 }
5994 #endif
5995 if (param_index < fastcall_nb_regs) {
5996
5997 -= 4;
5998 o(0x89);
5999 (fastcall_regs[param_index], VT_LOCAL, NULL, loc);
6000 param_addr = loc;
6001 } else {
6002 param_addr = addr;
6003 addr += size;
6004 }
6005 sym_push(sym->v & ~SYM_FIELD, type,
6006 VT_LOCAL | VT_LVAL, param_addr);
6007 param_index++;
6008 }
6009 func_ret_sub = 0;
6010
6011 if (func_call == FUNC_STDCALL)
6012 func_ret_sub = addr - 8;
6013
6014
6015 if (do_bounds_check) {
6016 oad(0xb8, 0);
6017 (0xb8, 0);
6018 = lbounds_section->data_offset;
6019 }
6020 }
6021
6022
6023 void gfunc_epilog(void)
6024 {
6025 int v, saved_ind;
6026
6027 #ifdef CONFIG_TCC_BCHECK
6028 if (do_bounds_check && func_bound_offset != lbounds_section->data_offset) {
6029 int saved_ind;
6030 int *bounds_ptr;
6031 Sym *sym, *sym_data;
6032
6033 = section_ptr_add(lbounds_section, sizeof(int));
6034 *bounds_ptr = 0;
6035
6036 = ind;
6037 ind = func_sub_sp_offset;
6038 sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
6039 func_bound_offset, lbounds_section->data_offset);
6040 greloc(cur_text_section, sym_data,
6041 ind + 1, R_386_32);
6042 oad(0xb8, 0);
6043 = external_global_sym(TOK___bound_local_new, &func_old_type, 0);
6044 greloc(cur_text_section, sym,
6045 ind + 1, R_386_PC32);
6046 oad(0xe8, -4);
6047 ind = saved_ind;
6048
6049 (0x5250);
6050 (cur_text_section, sym_data,
6051 ind + 1, R_386_32);
6052 oad(0xb8, 0);
6053 = external_global_sym(TOK___bound_local_delete, &func_old_type, 0);
6054 greloc(cur_text_section, sym,
6055 ind + 1, R_386_PC32);
6056 oad(0xe8, -4);
6057 o(0x585a);
6058 }
6059 #endif
6060 o(0xc9);
6061 if (func_ret_sub == 0) {
6062 o(0xc3);
6063 } else {
6064 o(0xc2);
6065 (func_ret_sub);
6066 g(func_ret_sub >> 8);
6067 }
6068
6069
6070 = (-loc + 3) & -4;
6071 saved_ind = ind;
6072 ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
6073 #ifdef TCC_TARGET_PE
6074 if (v >= 4096) {
6075 Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0);
6076 oad(0xb8, v);
6077 (0xe8, -4);
6078 (cur_text_section, sym, ind-4, R_386_PC32);
6079 } else
6080 #endif
6081 {
6082 o(0xe58955);
6083 (0xec81);
6084 (v);
6085 #if FUNC_PROLOG_SIZE == 10
6086 o(0x90);
6087 #endif
6088 }
6089 ind = saved_ind;
6090 }
6091
6092
6093 long gjmp(int t)
6094 {
6095 return psym(0xe9, t);
6096 }
6097
6098
6099 void gjmp_addr(int a)
6100 {
6101 int r;
6102 r = a - ind - 2;
6103 if (r == (char)r) {
6104 g(0xeb);
6105 g(r);
6106 } else {
6107 oad(0xe9, a - ind - 5);
6108 }
6109 }
6110
6111
6112 int gtst(int inv, int t)
6113 {
6114 int v, *p;
6115
6116 v = vtop->r & VT_VALMASK;
6117 if (v == VT_CMP) {
6118
6119 (0x0f);
6120 t = psym((vtop->c.i - 16) ^ inv, t);
6121 } else if (v == VT_JMP || v == VT_JMPI) {
6122
6123 if ((v & 1) == inv) {
6124
6125 = &vtop->c.i;
6126 while (*p != 0)
6127 p = (int *)(cur_text_section->data + *p);
6128 *p = t;
6129 t = vtop->c.i;
6130 } else {
6131 t = gjmp(t);
6132 gsym(vtop->c.i);
6133 }
6134 } else {
6135 if (is_float(vtop->type.t)) {
6136 vpushi(0);
6137 gen_op(TOK_NE);
6138 }
6139 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
6140
6141 if ((vtop->c.i != 0) != inv)
6142 t = gjmp(t);
6143 } else {
6144 v = gv(RC_INT);
6145 o(0x85);
6146 o(0xc0 + v * 9);
6147 g(0x0f);
6148 t = psym(0x85 ^ inv, t);
6149 }
6150 }
6151 vtop--;
6152 return t;
6153 }
6154
6155
6156 void gen_opi(int op)
6157 {
6158 int r, fr, opc, c;
6159
6160 switch(op) {
6161 case '+':
6162 case TOK_ADDC1:
6163 = 0;
6164 gen_op8:
6165 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
6166
6167 ();
6168 r = gv(RC_INT);
6169 vswap();
6170 c = vtop->c.i;
6171 if (c == (char)c) {
6172
6173 (0x83);
6174 o(0xc0 | (opc << 3) | r);
6175 g(c);
6176 } else {
6177 o(0x81);
6178 oad(0xc0 | (opc << 3) | r, c);
6179 }
6180 } else {
6181 gv2(RC_INT, RC_INT);
6182 r = vtop[-1].r;
6183 fr = vtop[0].r;
6184 o((opc << 3) | 0x01);
6185 o(0xc0 + r + fr * 8);
6186 }
6187 vtop--;
6188 if (op >= TOK_ULT && op <= TOK_GT) {
6189 vtop->r = VT_CMP;
6190 vtop->c.i = op;
6191 }
6192 break;
6193 case '-':
6194 case TOK_SUBC1:
6195 = 5;
6196 goto gen_op8;
6197 case TOK_ADDC2:
6198 = 2;
6199 goto gen_op8;
6200 case TOK_SUBC2:
6201 = 3;
6202 goto gen_op8;
6203 case '&':
6204 opc = 4;
6205 goto gen_op8;
6206 case '^':
6207 opc = 6;
6208 goto gen_op8;
6209 case '|':
6210 opc = 1;
6211 goto gen_op8;
6212 case '*':
6213 gv2(RC_INT, RC_INT);
6214 r = vtop[-1].r;
6215 fr = vtop[0].r;
6216 vtop--;
6217 o(0xaf0f);
6218 (0xc0 + fr + r * 8);
6219 break;
6220 case TOK_SHL:
6221 opc = 4;
6222 goto gen_shift;
6223 case TOK_SHR:
6224 opc = 5;
6225 goto gen_shift;
6226 case TOK_SAR:
6227 opc = 7;
6228 gen_shift:
6229 opc = 0xc0 | (opc << 3);
6230 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
6231
6232 ();
6233 r = gv(RC_INT);
6234 vswap();
6235 c = vtop->c.i & 0x1f;
6236 o(0xc1);
6237 (opc | r);
6238 g(c);
6239 } else {
6240
6241 (RC_INT, RC_ECX);
6242 r = vtop[-1].r;
6243 o(0xd3);
6244 (opc | r);
6245 }
6246 vtop--;
6247 break;
6248 case '/':
6249 case TOK_UDIV:
6250 case TOK_PDIV:
6251 case '%':
6252 case TOK_UMOD:
6253 case TOK_UMULL:
6254
6255
6256 (RC_EAX, RC_ECX);
6257 r = vtop[-1].r;
6258 fr = vtop[0].r;
6259 vtop--;
6260 save_reg(TREG_EDX);
6261 if (op == TOK_UMULL) {
6262 o(0xf7);
6263 (0xe0 + fr);
6264 vtop->r2 = TREG_EDX;
6265 r = TREG_EAX;
6266 } else {
6267 if (op == TOK_UDIV || op == TOK_UMOD) {
6268 o(0xf7d231);
6269 (0xf0 + fr);
6270 } else {
6271 o(0xf799);
6272 (0xf8 + fr);
6273 }
6274 if (op == '%' || op == TOK_UMOD)
6275 r = TREG_EDX;
6276 else
6277 r = TREG_EAX;
6278 }
6279 vtop->r = r;
6280 break;
6281 default:
6282 opc = 7;
6283 goto gen_op8;
6284 }
6285 }
6286
6287
6288
6289
6290 void gen_opf(int op)
6291 {
6292 int a, ft, fc, swapped, r;
6293
6294
6295 if ((vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
6296 vswap();
6297 gv(RC_FLOAT);
6298 vswap();
6299 }
6300 if ((vtop[0].r & (VT_VALMASK | VT_LVAL)) == VT_CONST)
6301 gv(RC_FLOAT);
6302
6303
6304 if ((vtop[-1].r & VT_LVAL) &&
6305 (vtop[0].r & VT_LVAL)) {
6306 vswap();
6307 gv(RC_FLOAT);
6308 vswap();
6309 }
6310 swapped = 0;
6311
6312
6313 if (vtop[-1].r & VT_LVAL) {
6314 vswap();
6315 swapped = 1;
6316 }
6317 if (op >= TOK_ULT && op <= TOK_GT) {
6318
6319 (TREG_ST0, vtop);
6320 save_reg(TREG_EAX);
6321 if (op == TOK_GE || op == TOK_GT)
6322 swapped = !swapped;
6323 else if (op == TOK_EQ || op == TOK_NE)
6324 swapped = 0;
6325 if (swapped)
6326 o(0xc9d9);
6327 (0xe9da);
6328 (0xe0df);
6329 if (op == TOK_EQ) {
6330 o(0x45e480);
6331 (0x40fC80);
6332 } else if (op == TOK_NE) {
6333 o(0x45e480);
6334 (0x40f480);
6335 = TOK_NE;
6336 } else if (op == TOK_GE || op == TOK_LE) {
6337 o(0x05c4f6);
6338 = TOK_EQ;
6339 } else {
6340 o(0x45c4f6);
6341 = TOK_EQ;
6342 }
6343 vtop--;
6344 vtop->r = VT_CMP;
6345 vtop->c.i = op;
6346 } else {
6347
6348 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
6349 load(TREG_ST0, vtop);
6350 swapped = !swapped;
6351 }
6352
6353 switch(op) {
6354 default:
6355 case '+':
6356 a = 0;
6357 break;
6358 case '-':
6359 a = 4;
6360 if (swapped)
6361 a++;
6362 break;
6363 case '*':
6364 a = 1;
6365 break;
6366 case '/':
6367 a = 6;
6368 if (swapped)
6369 a++;
6370 break;
6371 }
6372 ft = vtop->type.t;
6373 fc = vtop->c.ul;
6374 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
6375 o(0xde);
6376 (0xc1 + (a << 3));
6377 } else {
6378
6379 = vtop->r;
6380 if ((r & VT_VALMASK) == VT_LLOCAL) {
6381 SValue v1;
6382 r = get_reg(RC_INT);
6383 v1.type.t = VT_INT;
6384 v1.r = VT_LOCAL | VT_LVAL;
6385 v1.c.ul = fc;
6386 load(r, &v1);
6387 fc = 0;
6388 }
6389
6390 if ((ft & VT_BTYPE) == VT_DOUBLE)
6391 o(0xdc);
6392 else
6393 o(0xd8);
6394 gen_modrm(a, r, vtop->sym, fc);
6395 }
6396 vtop--;
6397 }
6398 }
6399
6400
6401
6402 void gen_cvt_itof(int t)
6403 {
6404 save_reg(TREG_ST0);
6405 gv(RC_INT);
6406 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
6407
6408
6409 (0x50 + vtop->r2);
6410 (0x50 + (vtop->r & VT_VALMASK));
6411 (0x242cdf);
6412 (0x08c483);
6413 } else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
6414 (VT_INT | VT_UNSIGNED)) {
6415
6416 (0x6a);
6417 (0x00);
6418 o(0x50 + (vtop->r & VT_VALMASK));
6419 (0x242cdf);
6420 (0x08c483);
6421 } else {
6422
6423 (0x50 + (vtop->r & VT_VALMASK));
6424 (0x2404db);
6425 (0x04c483);
6426 }
6427 vtop->r = TREG_ST0;
6428 }
6429
6430
6431
6432 void gen_cvt_ftoi(int t)
6433 {
6434 int r, r2, size;
6435 Sym *sym;
6436 CType ushort_type;
6437
6438 ushort_type.t = VT_SHORT | VT_UNSIGNED;
6439
6440 gv(RC_FLOAT);
6441 if (t != VT_INT)
6442 size = 8;
6443 else
6444 size = 4;
6445
6446 o(0x2dd9);
6447 = external_global_sym(TOK___tcc_int_fpu_control,
6448 &ushort_type, VT_LVAL);
6449 greloc(cur_text_section, sym,
6450 ind, R_386_32);
6451 gen_le32(0);
6452
6453 oad(0xec81, size);
6454 if (size == 4)
6455 o(0x1cdb);
6456 else
6457 o(0x3cdf);
6458 (0x24);
6459 o(0x2dd9);
6460 = external_global_sym(TOK___tcc_fpu_control,
6461 &ushort_type, VT_LVAL);
6462 greloc(cur_text_section, sym,
6463 ind, R_386_32);
6464 gen_le32(0);
6465
6466 r = get_reg(RC_INT);
6467 o(0x58 + r);
6468 if (size == 8) {
6469 if (t == VT_LLONG) {
6470 vtop->r = r;
6471 = get_reg(RC_INT);
6472 o(0x58 + r2);
6473 ->r2 = r2;
6474 } else {
6475 o(0x04c483);
6476 }
6477 }
6478 vtop->r = r;
6479 }
6480
6481
6482 void gen_cvt_ftof(int t)
6483 {
6484
6485 (RC_FLOAT);
6486 }
6487
6488
6489 void ggoto(void)
6490 {
6491 gcall_or_jmp(1);
6492 vtop--;
6493 }
6494
6495
6496 #ifdef CONFIG_TCC_BCHECK
6497
6498
6499 void gen_bounded_ptr_add(void)
6500 {
6501 Sym *sym;
6502
6503
6504 (RC_EAX, RC_EDX);
6505
6506 -= 2;
6507 save_regs(0);
6508
6509 = external_global_sym(TOK___bound_ptr_add, &func_old_type, 0);
6510 greloc(cur_text_section, sym,
6511 ind + 1, R_386_PC32);
6512 oad(0xe8, -4);
6513
6514 ++;
6515 vtop->r = TREG_EAX | VT_BOUNDED;
6516
6517 ->c.ul = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel));
6518 }
6519
6520
6521
6522 void gen_bounded_ptr_deref(void)
6523 {
6524 int func;
6525 int size, align;
6526 Elf32_Rel *rel;
6527 Sym *sym;
6528
6529 size = 0;
6530
6531 if (!is_float(vtop->type.t)) {
6532 if (vtop->r & VT_LVAL_BYTE)
6533 size = 1;
6534 else if (vtop->r & VT_LVAL_SHORT)
6535 size = 2;
6536 }
6537 if (!size)
6538 size = type_size(&vtop->type, &align);
6539 switch(size) {
6540 case 1: func = TOK___bound_ptr_indir1; break;
6541 case 2: func = TOK___bound_ptr_indir2; break;
6542 case 4: func = TOK___bound_ptr_indir4; break;
6543 case 8: func = TOK___bound_ptr_indir8; break;
6544 case 12: func = TOK___bound_ptr_indir12; break;
6545 case 16: func = TOK___bound_ptr_indir16; break;
6546 default:
6547 error("unhandled size when derefencing bounded pointer");
6548 func = 0;
6549 break;
6550 }
6551
6552
6553
6554 = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.ul);
6555 sym = external_global_sym(func, &func_old_type, 0);
6556 if (!sym->c)
6557 put_extern_sym(sym, NULL, 0, 0);
6558 rel->r_info = ELF32_R_INFO(sym->c, ELF32_R_TYPE(rel->r_info));
6559 }
6560 #endif
6561
6562
6563
6564
6565
6566 #endif
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577 #ifdef CONFIG_TCC_STATIC
6578
6579 #define RTLD_LAZY 0x001
6580 #define RTLD_NOW 0x002
6581 #define RTLD_GLOBAL 0x100
6582 #define RTLD_DEFAULT NULL
6583
6584
6585 void *dlopen(const char *filename, int flag)
6586 {
6587 return NULL;
6588 }
6589
6590 const char *dlerror(void)
6591 {
6592 return "error";
6593 }
6594
6595 typedef struct TCCSyms {
6596 char *str;
6597 void *ptr;
6598 } TCCSyms;
6599
6600 #define TCCSYM(a) { #a, &a, },
6601
6602
6603 static TCCSyms tcc_syms[] = {
6604 #if !defined(CONFIG_TCCBOOT)
6605 TCCSYM(printf)
6606 TCCSYM(fprintf)
6607 TCCSYM(fopen)
6608 TCCSYM(fclose)
6609 #endif
6610 { NULL, NULL },
6611 };
6612
6613 void *resolve_sym(TCCState *s1, const char *symbol, int type)
6614 {
6615 TCCSyms *p;
6616 p = tcc_syms;
6617 while (p->str != NULL) {
6618 if (!strcmp(p->str, symbol))
6619 return p->ptr;
6620 p++;
6621 }
6622 return NULL;
6623 }
6624
6625 #elif !defined(WIN32)
6626
6627 #include <dlfcn.h>
6628
6629 void *resolve_sym(TCCState *s1, const char *sym, int type)
6630 {
6631 assert(0);
6632 return 0;
6633
6634 }
6635
6636 #endif
6637
6638
6639
6640
6641
6642
6643 int ieee_finite(double d)
6644 {
6645 int *p = (int *)&d;
6646 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
6647 }
6648
6649
6650 static char *pstrcpy(char *buf, int buf_size, const char *s)
6651 {
6652 char *q, *q_end;
6653 int c;
6654
6655 if (buf_size > 0) {
6656 q = buf;
6657 q_end = buf + buf_size - 1;
6658 while (q < q_end) {
6659 c = *s++;
6660 if (c == '\0')
6661 break;
6662 *q++ = c;
6663 }
6664 *q = '\0';
6665 }
6666 return buf;
6667 }
6668
6669
6670 static char *pstrcat(char *buf, int buf_size, const char *s)
6671 {
6672 int len;
6673 len = strlen(buf);
6674 if (len < buf_size)
6675 pstrcpy(buf + len, buf_size - len, s);
6676 return buf;
6677 }
6678
6679 static int strstart(const char *str, const char *val, const char **ptr)
6680 {
6681 const char *p, *q;
6682 p = str;
6683 q = val;
6684 while (*q != '\0') {
6685 if (*p != *q)
6686 return 0;
6687 p++;
6688 q++;
6689 }
6690 if (ptr)
6691 *ptr = p;
6692 return 1;
6693 }
6694
6695
6696 #ifdef MEM_DEBUG
6697 int mem_cur_size;
6698 int mem_max_size;
6699 #endif
6700
6701 static inline void tcc_free(void *ptr)
6702 {
6703 #ifdef MEM_DEBUG
6704 mem_cur_size -= malloc_usable_size(ptr);
6705 #endif
6706 free(ptr);
6707 }
6708
6709 static void *tcc_malloc(unsigned long size)
6710 {
6711 void *ptr;
6712 ptr = malloc(size);
6713 if (!ptr && size)
6714 error("memory full");
6715 #ifdef MEM_DEBUG
6716 mem_cur_size += malloc_usable_size(ptr);
6717 if (mem_cur_size > mem_max_size)
6718 mem_max_size = mem_cur_size;
6719 #endif
6720 return ptr;
6721 }
6722
6723 static void *tcc_mallocz(unsigned long size)
6724 {
6725 void *ptr;
6726 ptr = tcc_malloc(size);
6727 memset(ptr, 0, size);
6728 return ptr;
6729 }
6730
6731 static inline void *tcc_realloc(void *ptr, unsigned long size)
6732 {
6733 void *ptr1;
6734 #ifdef MEM_DEBUG
6735 mem_cur_size -= malloc_usable_size(ptr);
6736 #endif
6737 ptr1 = realloc(ptr, size);
6738 #ifdef MEM_DEBUG
6739
6740 mem_cur_size += malloc_usable_size(ptr1);
6741 if (mem_cur_size > mem_max_size)
6742 mem_max_size = mem_cur_size;
6743 #endif
6744 return ptr1;
6745 }
6746
6747 static char *tcc_strdup(const char *str)
6748 {
6749 char *ptr;
6750 ptr = tcc_malloc(strlen(str) + 1);
6751 strcpy(ptr, str);
6752 return ptr;
6753 }
6754
6755 #define free(p) use_tcc_free(p)
6756 #define malloc(s) use_tcc_malloc(s)
6757 #define realloc(p, s) use_tcc_realloc(p, s)
6758
6759 static void dynarray_add(void ***ptab, int *nb_ptr, void *data)
6760 {
6761 int nb, nb_alloc;
6762 void **pp;
6763
6764 nb = *nb_ptr;
6765 pp = *ptab;
6766
6767 if ((nb & (nb - 1)) == 0) {
6768 if (!nb)
6769 nb_alloc = 1;
6770 else
6771 nb_alloc = nb * 2;
6772 pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
6773 if (!pp)
6774 error("memory full");
6775 *ptab = pp;
6776 }
6777 pp[nb++] = data;
6778 *nb_ptr = nb;
6779 }
6780
6781
6782 static Sym *__sym_malloc(void)
6783 {
6784 Sym *sym_pool, *sym, *last_sym;
6785 int i;
6786
6787 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
6788
6789 last_sym = sym_free_first;
6790 sym = sym_pool;
6791 for(i = 0; i < SYM_POOL_NB; i++) {
6792 sym->next = last_sym;
6793 last_sym = sym;
6794 sym++;
6795 }
6796 sym_free_first = last_sym;
6797 return last_sym;
6798 }
6799
6800 static inline Sym *sym_malloc(void)
6801 {
6802 Sym *sym;
6803 sym = sym_free_first;
6804 if (!sym)
6805 sym = __sym_malloc();
6806 sym_free_first = sym->next;
6807 return sym;
6808 }
6809
6810 static inline void sym_free(Sym *sym)
6811 {
6812 sym->next = sym_free_first;
6813 sym_free_first = sym;
6814 }
6815
6816 Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
6817 {
6818 Section *sec;
6819
6820 sec = tcc_mallocz(sizeof(Section) + strlen(name));
6821 strcpy(sec->name, name);
6822 sec->sh_type = sh_type;
6823 sec->sh_flags = sh_flags;
6824 switch(sh_type) {
6825 case SHT_HASH:
6826 case SHT_REL:
6827 case SHT_DYNSYM:
6828 case SHT_SYMTAB:
6829 case SHT_DYNAMIC:
6830 sec->sh_addralign = 4;
6831 break;
6832 case SHT_STRTAB:
6833 sec->sh_addralign = 1;
6834 break;
6835 default:
6836 sec->sh_addralign = 32;
6837 break;
6838 }
6839
6840
6841 if (!(sh_flags & SHF_PRIVATE)) {
6842 sec->sh_num = s1->nb_sections;
6843 dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);
6844 }
6845 return sec;
6846 }
6847
6848 static void free_section(Section *s)
6849 {
6850 tcc_free(s->data);
6851 tcc_free(s);
6852 }
6853
6854
6855 static void section_realloc(Section *sec, unsigned long new_size)
6856 {
6857 unsigned long size;
6858 unsigned char *data;
6859
6860 size = sec->data_allocated;
6861 if (size == 0)
6862 size = 1;
6863 while (size < new_size)
6864 size = size * 2;
6865 data = tcc_realloc(sec->data, size);
6866 if (!data)
6867 error("memory full");
6868 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
6869 sec->data = data;
6870 sec->data_allocated = size;
6871 }
6872
6873
6874
6875 static void *section_ptr_add(Section *sec, unsigned long size)
6876 {
6877 unsigned long offset, offset1;
6878
6879 offset = sec->data_offset;
6880 offset1 = offset + size;
6881 if (offset1 > sec->data_allocated)
6882 section_realloc(sec, offset1);
6883 sec->data_offset = offset1;
6884 return sec->data + offset;
6885 }
6886
6887
6888
6889 *find_section(TCCState *s1, const char *name)
6890 {
6891 Section *sec;
6892 int i;
6893 for(i = 1; i < s1->nb_sections; i++) {
6894 sec = s1->sections[i];
6895 if (!strcmp(name, sec->name))
6896 return sec;
6897 }
6898
6899 return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
6900 }
6901
6902 #define SECTION_ABS ((void *)1)
6903
6904
6905
6906 static void put_extern_sym2(Sym *sym, Section *section,
6907 unsigned long value, unsigned long size,
6908 int can_add_underscore)
6909 {
6910 int sym_type, sym_bind, sh_num, info;
6911 Elf32_Sym *esym;
6912 const char *name;
6913 char buf1[256];
6914
6915 if (section == NULL)
6916 sh_num = SHN_UNDEF;
6917 else if (section == SECTION_ABS)
6918 sh_num = SHN_ABS;
6919 else
6920 sh_num = section->sh_num;
6921 if (!sym->c) {
6922 if ((sym->type.t & VT_BTYPE) == VT_FUNC)
6923 sym_type = STT_FUNC;
6924 else
6925 sym_type = STT_OBJECT;
6926 if (sym->type.t & VT_STATIC)
6927 sym_bind = STB_LOCAL;
6928 else
6929 sym_bind = STB_GLOBAL;
6930
6931 name = get_tok_str(sym->v, NULL);
6932 #ifdef CONFIG_TCC_BCHECK
6933 if (do_bounds_check) {
6934 char buf[32];
6935
6936
6937
6938
6939 switch(sym->v) {
6940 #if 0
6941
6942 case TOK_malloc:
6943 case TOK_free:
6944 case TOK_realloc:
6945 case TOK_memalign:
6946 case TOK_calloc:
6947 #endif
6948 case TOK_memcpy:
6949 case TOK_memmove:
6950 case TOK_memset:
6951 case TOK_strlen:
6952 case TOK_strcpy:
6953 strcpy(buf, "__bound_");
6954 strcat(buf, name);
6955 name = buf;
6956 break;
6957 }
6958 }
6959 #endif
6960 if (tcc_state->leading_underscore && can_add_underscore) {
6961 buf1[0] = '_';
6962 pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
6963 name = buf1;
6964 }
6965 info = ELF32_ST_INFO(sym_bind, sym_type);
6966 sym->c = add_elf_sym(symtab_section, value, size, info, 0, sh_num, name);
6967 } else {
6968 esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
6969 esym->st_value = value;
6970 esym->st_size = size;
6971 esym->st_shndx = sh_num;
6972 }
6973 }
6974
6975 static void put_extern_sym(Sym *sym, Section *section,
6976 unsigned long value, unsigned long size)
6977 {
6978 put_extern_sym2(sym, section, value, size, 1);
6979 }
6980
6981
6982 static void greloc(Section *s, Sym *sym, unsigned long offset, int type)
6983 {
6984 if (!sym->c)
6985 put_extern_sym(sym, NULL, 0, 0);
6986
6987 (symtab_section, s, offset, type, sym->c);
6988 }
6989
6990 static inline int isid(int c)
6991 {
6992 return (c >= 'a' && c <= 'z') ||
6993 (c >= 'A' && c <= 'Z') ||
6994 c == '_';
6995 }
6996
6997 static inline int isnum(int c)
6998 {
6999 return c >= '0' && c <= '9';
7000 }
7001
7002 static inline int isoct(int c)
7003 {
7004 return c >= '0' && c <= '7';
7005 }
7006
7007 static inline int toup(int c)
7008 {
7009 if (c >= 'a' && c <= 'z')
7010 return c - 'a' + 'A';
7011 else
7012 return c;
7013 }
7014
7015 static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
7016 {
7017 int len;
7018 len = strlen(buf);
7019 vsnprintf(buf + len, buf_size - len, fmt, ap);
7020 }
7021
7022 static void strcat_printf(char *buf, int buf_size, const char *fmt, ...)
7023 {
7024 va_list ap;
7025 va_start(ap, fmt);
7026 strcat_vprintf(buf, buf_size, fmt, ap);
7027 va_end(ap);
7028 }
7029
7030 void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
7031 {
7032 char buf[2048];
7033 BufferedFile **f;
7034
7035 buf[0] = '\0';
7036 if (file) {
7037 for(f = s1->include_stack; f < s1->include_stack_ptr; f++)
7038 strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n",
7039 (*f)->filename, (*f)->line_num);
7040 if (file->line_num > 0) {
7041 strcat_printf(buf, sizeof(buf),
7042 "%s:%d: ", file->filename, file->line_num);
7043 } else {
7044 strcat_printf(buf, sizeof(buf),
7045 "%s: ", file->filename);
7046 }
7047 } else {
7048 strcat_printf(buf, sizeof(buf),
7049 "tcc: ");
7050 }
7051 if (is_warning)
7052 strcat_printf(buf, sizeof(buf), "warning: ");
7053 strcat_vprintf(buf, sizeof(buf), fmt, ap);
7054
7055 if (!s1->error_func) {
7056
7057 (stderr, "%s\n", buf);
7058 } else {
7059 s1->error_func(s1->error_opaque, buf);
7060 }
7061 if (!is_warning || s1->warn_error)
7062 s1->nb_errors++;
7063 }
7064
7065 #ifdef LIBTCC
7066 void tcc_set_error_func(TCCState *s, void *error_opaque,
7067 void (*error_func)(void *opaque, const char *msg))
7068 {
7069 s->error_opaque = error_opaque;
7070 s->error_func = error_func;
7071 }
7072 #endif
7073
7074
7075 void error_noabort(const char *fmt, ...)
7076 {
7077 TCCState *s1 = tcc_state;
7078 va_list ap;
7079
7080 va_start(ap, fmt);
7081 error1(s1, 0, fmt, ap);
7082 va_end(ap);
7083 }
7084
7085 void error(const char *fmt, ...)
7086 {
7087 TCCState *s1 = tcc_state;
7088 va_list ap;
7089
7090 va_start(ap, fmt);
7091 error1(s1, 0, fmt, ap);
7092 va_end(ap);
7093
7094 if (s1->error_set_jmp_enabled) {
7095 longjmp(s1->error_jmp_buf, 1);
7096 } else {
7097
7098 (1);
7099 }
7100 }
7101
7102 void expect(const char *msg)
7103 {
7104 error("%s expected", msg);
7105 }
7106
7107 void warning(const char *fmt, ...)
7108 {
7109 TCCState *s1 = tcc_state;
7110 va_list ap;
7111
7112 if (s1->warn_none)
7113 return;
7114
7115 va_start(ap, fmt);
7116 error1(s1, 1, fmt, ap);
7117 va_end(ap);
7118 }
7119
7120 void skip(int c)
7121 {
7122 if (tok != c)
7123 error("'%c' expected", c);
7124 next();
7125 }
7126
7127 static void test_lvalue(void)
7128 {
7129 if (!(vtop->r & VT_LVAL))
7130 expect("lvalue");
7131 }
7132
7133
7134 static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
7135 {
7136 TokenSym *ts, **ptable;
7137 int i;
7138
7139 if (tok_ident >= SYM_FIRST_ANOM)
7140 error("memory full");
7141
7142
7143 = tok_ident - TOK_IDENT;
7144 if ((i % TOK_ALLOC_INCR) == 0) {
7145 ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
7146 if (!ptable)
7147 error("memory full");
7148 table_ident = ptable;
7149 }
7150
7151 ts = tcc_malloc(sizeof(TokenSym) + len);
7152 table_ident[i] = ts;
7153 ts->tok = tok_ident++;
7154 ts->sym_define = NULL;
7155 ts->sym_label = NULL;
7156 ts->sym_struct = NULL;
7157 ts->sym_identifier = NULL;
7158 ts->len = len;
7159 ts->hash_next = NULL;
7160 memcpy(ts->str, str, len);
7161 ts->str[len] = '\0';
7162 *pts = ts;
7163 return ts;
7164 }
7165
7166 #define TOK_HASH_INIT 1
7167 #define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
7168
7169
7170 static TokenSym *tok_alloc(const char *str, int len)
7171 {
7172 TokenSym *ts, **pts;
7173 int i;
7174 unsigned int h;
7175
7176 h = TOK_HASH_INIT;
7177 for(i=0;i<len;i++)
7178 h = TOK_HASH_FUNC(h, ((unsigned char *)str)[i]);
7179 h &= (TOK_HASH_SIZE - 1);
7180
7181 pts = &hash_ident[h];
7182 for(;;) {
7183 ts = *pts;
7184 if (!ts)
7185 break;
7186 if (ts->len == len && !memcmp(ts->str, str, len))
7187 return ts;
7188 pts = &(ts->hash_next);
7189 }
7190 return tok_alloc_new(pts, str, len);
7191 }
7192
7193
7194
7195 static void cstr_realloc(CString *cstr, int new_size)
7196 {
7197 int size;
7198 void *data;
7199
7200 size = cstr->size_allocated;
7201 if (size == 0)
7202 size = 8;
7203 while (size < new_size)
7204 size = size * 2;
7205 data = tcc_realloc(cstr->data_allocated, size);
7206 if (!data)
7207 error("memory full");
7208 cstr->data_allocated = data;
7209 cstr->size_allocated = size;
7210 cstr->data = data;
7211 }
7212
7213
7214 static inline void cstr_ccat(CString *cstr, int ch)
7215 {
7216 int size;
7217 size = cstr->size + 1;
7218 if (size > cstr->size_allocated)
7219 cstr_realloc(cstr, size);
7220 ((unsigned char *)cstr->data)[size - 1] = ch;
7221 cstr->size = size;
7222 }
7223
7224 static void cstr_cat(CString *cstr, const char *str)
7225 {
7226 int c;
7227 for(;;) {
7228 c = *str;
7229 if (c == '\0')
7230 break;
7231 cstr_ccat(cstr, c);
7232 str++;
7233 }
7234 }
7235
7236
7237 static void cstr_wccat(CString *cstr, int ch)
7238 {
7239 int size;
7240 size = cstr->size + sizeof(int);
7241 if (size > cstr->size_allocated)
7242 cstr_realloc(cstr, size);
7243 *(int *)(((unsigned char *)cstr->data) + size - sizeof(int)) = ch;
7244 cstr->size = size;
7245 }
7246
7247 static void cstr_new(CString *cstr)
7248 {
7249 memset(cstr, 0, sizeof(CString));
7250 }
7251
7252
7253 static void cstr_free(CString *cstr)
7254 {
7255 tcc_free(cstr->data_allocated);
7256 cstr_new(cstr);
7257 }
7258
7259 #define cstr_reset(cstr) cstr_free(cstr)
7260
7261
7262 static void add_char(CString *cstr, int c)
7263 {
7264 if (c == '\'' || c == '\"' || c == '\\') {
7265
7266 (cstr, '\\');
7267 }
7268 if (c >= 32 && c <= 126) {
7269 cstr_ccat(cstr, c);
7270 } else {
7271 cstr_ccat(cstr, '\\');
7272 if (c == '\n') {
7273 cstr_ccat(cstr, 'n');
7274 } else {
7275 cstr_ccat(cstr, '0' + ((c >> 6) & 7));
7276 cstr_ccat(cstr, '0' + ((c >> 3) & 7));
7277 cstr_ccat(cstr, '0' + (c & 7));
7278 }
7279 }
7280 }
7281
7282
7283
7284 char *get_tok_str(int v, CValue *cv)
7285 {
7286 static char buf[STRING_MAX_SIZE + 1];
7287 static CString cstr_buf;
7288 CString *cstr;
7289 unsigned char *q;
7290 char *p;
7291 int i, len;
7292
7293
7294 (&cstr_buf);
7295 cstr_buf.data = buf;
7296 cstr_buf.size_allocated = sizeof(buf);
7297 p = buf;
7298
7299 switch(v) {
7300 case TOK_CINT:
7301 case TOK_CUINT:
7302
7303 (p, "%u", cv->ui);
7304 break;
7305 case TOK_CLLONG:
7306 case TOK_CULLONG:
7307
7308 (p, "%Lu", cv->ull);
7309 break;
7310 case TOK_CCHAR:
7311 case TOK_LCHAR:
7312 cstr_ccat(&cstr_buf, '\'');
7313 add_char(&cstr_buf, cv->i);
7314 cstr_ccat(&cstr_buf, '\'');
7315 cstr_ccat(&cstr_buf, '\0');
7316 break;
7317 case TOK_PPNUM:
7318 cstr = cv->cstr;
7319 len = cstr->size - 1;
7320 for(i=0;i<len;i++)
7321 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
7322 cstr_ccat(&cstr_buf, '\0');
7323 break;
7324 case TOK_STR:
7325 case TOK_LSTR:
7326 cstr = cv->cstr;
7327 cstr_ccat(&cstr_buf, '\"');
7328 if (v == TOK_STR) {
7329 len = cstr->size - 1;
7330 for(i=0;i<len;i++)
7331 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
7332 } else {
7333 len = (cstr->size / sizeof(int)) - 1;
7334 for(i=0;i<len;i++)
7335 add_char(&cstr_buf, ((int *)cstr->data)[i]);
7336 }
7337 cstr_ccat(&cstr_buf, '\"');
7338 cstr_ccat(&cstr_buf, '\0');
7339 break;
7340 case TOK_LT:
7341 v = '<';
7342 goto addv;
7343 case TOK_GT:
7344 v = '>';
7345 goto addv;
7346 case TOK_A_SHL:
7347 return strcpy(p, "<<=");
7348 case TOK_A_SAR:
7349 return strcpy(p, ">>=");
7350 default:
7351 if (v < TOK_IDENT) {
7352
7353 = tok_two_chars;
7354 while (*q) {
7355 if (q[2] == v) {
7356 *p++ = q[0];
7357 *p++ = q[1];
7358 *p = '\0';
7359 return buf;
7360 }
7361 q += 3;
7362 }
7363 addv:
7364 *p++ = v;
7365 *p = '\0';
7366 } else if (v < tok_ident) {
7367 return table_ident[v - TOK_IDENT]->str;
7368 } else if (v >= SYM_FIRST_ANOM) {
7369
7370 (p, "L.%u", v - SYM_FIRST_ANOM);
7371 } else {
7372
7373 return NULL;
7374 }
7375 break;
7376 }
7377 return cstr_buf.data;
7378 }
7379
7380
7381 static Sym *sym_push2(Sym **ps, long v, long t, long c)
7382 {
7383 Sym *s;
7384 s = sym_malloc();
7385 s->v = v;
7386 s->type.t = t;
7387 s->c = c;
7388 s->next = NULL;
7389
7390 ->prev = *ps;
7391 *ps = s;
7392 return s;
7393 }
7394
7395
7396
7397 static Sym *sym_find2(Sym *s, int v)
7398 {
7399 while (s) {
7400 if (s->v == v)
7401 return s;
7402 s = s->prev;
7403 }
7404 return NULL;
7405 }
7406
7407
7408 static inline Sym *struct_find(int v)
7409 {
7410 v -= TOK_IDENT;
7411 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
7412 return NULL;
7413 return table_ident[v]->sym_struct;
7414 }
7415
7416
7417 static inline Sym *sym_find(int v)
7418 {
7419 v -= TOK_IDENT;
7420 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
7421 return NULL;
7422 return table_ident[v]->sym_identifier;
7423 }
7424
7425
7426 static Sym *sym_push(int v, CType *type, int r, int c)
7427 {
7428 Sym *s, **ps;
7429 TokenSym *ts;
7430
7431 if (local_stack)
7432 ps = &local_stack;
7433 else
7434 ps = &global_stack;
7435 s = sym_push2(ps, v, type->t, c);
7436 s->type.ref = type->ref;
7437 s->r = r;
7438
7439
7440 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
7441
7442 = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
7443 if (v & SYM_STRUCT)
7444 ps = &ts->sym_struct;
7445 else
7446 ps = &ts->sym_identifier;
7447 s->prev_tok = *ps;
7448 *ps = s;
7449 }
7450 return s;
7451 }
7452
7453
7454 static Sym *global_identifier_push(int v, int t, int c)
7455 {
7456 Sym *s, **ps;
7457 s = sym_push2(&global_stack, v, t, c);
7458
7459 if (v < SYM_FIRST_ANOM) {
7460 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
7461
7462
7463 while (*ps != NULL)
7464 ps = &(*ps)->prev_tok;
7465 s->prev_tok = NULL;
7466 *ps = s;
7467 }
7468 return s;
7469 }
7470
7471
7472 static void sym_pop(Sym **ptop, Sym *b)
7473 {
7474 Sym *s, *ss, **ps;
7475 TokenSym *ts;
7476 int v;
7477
7478 s = *ptop;
7479 while(s != b) {
7480 ss = s->prev;
7481 v = s->v;
7482
7483
7484 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
7485 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
7486 if (v & SYM_STRUCT)
7487 ps = &ts->sym_struct;
7488 else
7489 ps = &ts->sym_identifier;
7490 *ps = s->prev_tok;
7491 }
7492 sym_free(s);
7493 s = ss;
7494 }
7495 *ptop = b;
7496 }
7497
7498
7499
7500 *tcc_open(TCCState *s1, const char *filename)
7501 {
7502 int fd;
7503 BufferedFile *bf;
7504
7505 fd = open(filename, O_RDONLY | O_BINARY);
7506 if (fd < 0)
7507 return NULL;
7508 bf = tcc_malloc(sizeof(BufferedFile));
7509 if (!bf) {
7510 close(fd);
7511 return NULL;
7512 }
7513 bf->fd = fd;
7514 bf->buf_ptr = bf->buffer;
7515 bf->buf_end = bf->buffer;
7516 bf->buffer[0] = CH_EOB;
7517 (bf->filename, sizeof(bf->filename), filename);
7518 bf->line_num = 1;
7519 bf->ifndef_macro = 0;
7520 bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
7521
7522 return bf;
7523 }
7524
7525 void tcc_close(BufferedFile *bf)
7526 {
7527 total_lines += bf->line_num;
7528 close(bf->fd);
7529 tcc_free(bf);
7530 }
7531
7532
7533 static int tcc_peekc_slow(BufferedFile *bf)
7534 {
7535 int len;
7536
7537 if (bf->buf_ptr >= bf->buf_end) {
7538 if (bf->fd != -1) {
7539 #if defined(PARSE_DEBUG)
7540 len = 8;
7541 #else
7542 len = IO_BUF_SIZE;
7543 #endif
7544 len = read(bf->fd, bf->buffer, len);
7545 if (len < 0)
7546 len = 0;
7547 } else {
7548 len = 0;
7549 }
7550 total_bytes += len;
7551 bf->buf_ptr = bf->buffer;
7552 bf->buf_end = bf->buffer + len;
7553 *bf->buf_end = CH_EOB;
7554 }
7555 if (bf->buf_ptr < bf->buf_end) {
7556 return bf->buf_ptr[0];
7557 } else {
7558 bf->buf_ptr = bf->buf_end;
7559 return CH_EOF;
7560 }
7561 }
7562
7563
7564
7565 static int handle_eob(void)
7566 {
7567 return tcc_peekc_slow(file);
7568 }
7569
7570
7571 static inline void inp(void)
7572 {
7573 ch = *(++(file->buf_ptr));
7574
7575 if (ch == CH_EOB)
7576 ch = handle_eob();
7577 }
7578
7579
7580 static void handle_stray(void)
7581 {
7582 while (ch == '\\') {
7583 inp();
7584 if (ch == '\n') {
7585 file->line_num++;
7586 inp();
7587 } else if (ch == '\r') {
7588 inp();
7589 if (ch != '\n')
7590 goto fail;
7591 file->line_num++;
7592 inp();
7593 } else {
7594 fail:
7595 error("stray '\\' in program");
7596 }
7597 }
7598 }
7599
7600
7601
7602 static int handle_stray1(uint8_t *p)
7603 {
7604 int c;
7605
7606 if (p >= file->buf_end) {
7607 file->buf_ptr = p;
7608 c = handle_eob();
7609 p = file->buf_ptr;
7610 if (c == '\\')
7611 goto parse_stray;
7612 } else {
7613 parse_stray:
7614 file->buf_ptr = p;
7615 ch = *p;
7616 handle_stray();
7617 p = file->buf_ptr;
7618 c = *p;
7619 }
7620 return c;
7621 }
7622
7623
7624 #define PEEKC_EOB(c, p)\
7625 {\
7626 p++;\
7627 c = *p;\
7628 if (c == '\\') {\
7629 file->buf_ptr = p;\
7630 c = handle_eob();\
7631 p = file->buf_ptr;\
7632 }\
7633 }
7634
7635
7636 #define PEEKC(c, p)\
7637 {\
7638 p++;\
7639 c = *p;\
7640 if (c == '\\') {\
7641 c = handle_stray1(p);\
7642 p = file->buf_ptr;\
7643 }\
7644 }
7645
7646
7647
7648
7649 static void minp(void)
7650 {
7651 inp();
7652 if (ch == '\\')
7653 handle_stray();
7654 }
7655
7656
7657
7658 static uint8_t *parse_line_comment(uint8_t *p)
7659 {
7660 int c;
7661
7662 p++;
7663 for(;;) {
7664 c = *p;
7665 redo:
7666 if (c == '\n' || c == CH_EOF) {
7667 break;
7668 } else if (c == '\\') {
7669 file->buf_ptr = p;
7670 c = handle_eob();
7671 p = file->buf_ptr;
7672 if (c == '\\') {
7673 PEEKC_EOB(c, p);
7674 if (c == '\n') {
7675 file->line_num++;
7676 PEEKC_EOB(c, p);
7677 } else if (c == '\r') {
7678 PEEKC_EOB(c, p);
7679 if (c == '\n') {
7680 file->line_num++;
7681 PEEKC_EOB(c, p);
7682 }
7683 }
7684 } else {
7685 goto redo;
7686 }
7687 } else {
7688 p++;
7689 }
7690 }
7691 return p;
7692 }
7693
7694
7695 static uint8_t *parse_comment(uint8_t *p)
7696 {
7697 int c;
7698
7699 p++;
7700 for(;;) {
7701
7702 for(;;) {
7703 c = *p;
7704 if (c == '\n' || c == '*' || c == '\\')
7705 break;
7706 p++;
7707 c = *p;
7708 if (c == '\n' || c == '*' || c == '\\')
7709 break;
7710 p++;
7711 }
7712
7713 if (c == '\n') {
7714 file->line_num++;
7715 p++;
7716 } else if (c == '*') {
7717 p++;
7718 for(;;) {
7719 c = *p;
7720 if (c == '*') {
7721 p++;
7722 } else if (c == '/') {
7723 goto end_of_comment;
7724 } else if (c == '\\') {
7725 file->buf_ptr = p;
7726 c = handle_eob();
7727 p = file->buf_ptr;
7728 if (c == '\\') {
7729
7730 while (c == '\\') {
7731 PEEKC_EOB(c, p);
7732 if (c == '\n') {
7733 file->line_num++;
7734 PEEKC_EOB(c, p);
7735 } else if (c == '\r') {
7736 PEEKC_EOB(c, p);
7737 if (c == '\n') {
7738 file->line_num++;
7739 PEEKC_EOB(c, p);
7740 }
7741 } else {
7742 goto after_star;
7743 }
7744 }
7745 }
7746 } else {
7747 break;
7748 }
7749 }
7750 after_star: ;
7751 } else {
7752
7753 ->buf_ptr = p;
7754 c = handle_eob();
7755 p = file->buf_ptr;
7756 if (c == CH_EOF) {
7757 error("unexpected end of file in comment");
7758 } else if (c == '\\') {
7759 p++;
7760 }
7761 }
7762 }
7763 end_of_comment:
7764 p++;
7765 return p;
7766 }
7767
7768 #define cinp minp
7769
7770
7771 static inline int is_space(int ch)
7772 {
7773 return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
7774 }
7775
7776 static inline void skip_spaces(void)
7777 {
7778 while (is_space(ch))
7779 cinp();
7780 }
7781
7782
7783 static uint8_t *parse_pp_string(uint8_t *p,
7784 int sep, CString *str)
7785 {
7786 int c;
7787 p++;
7788 for(;;) {
7789 c = *p;
7790 if (c == sep) {
7791 break;
7792 } else if (c == '\\') {
7793 file->buf_ptr = p;
7794 c = handle_eob();
7795 p = file->buf_ptr;
7796 if (c == CH_EOF) {
7797 unterminated_string:
7798
7799 ("missing terminating %c character", sep);
7800 } else if (c == '\\') {
7801
7802 (c, p);
7803 if (c == '\n') {
7804 file->line_num++;
7805 p++;
7806 } else if (c == '\r') {
7807 PEEKC_EOB(c, p);
7808 if (c != '\n')
7809 expect("'\n' after '\r'");
7810 file->line_num++;
7811 p++;
7812 } else if (c == CH_EOF) {
7813 goto unterminated_string;
7814 } else {
7815 if (str) {
7816 cstr_ccat(str, '\\');
7817 cstr_ccat(str, c);
7818 }
7819 p++;
7820 }
7821 }
7822 } else if (c == '\n') {
7823 file->line_num++;
7824 goto add_char;
7825 } else if (c == '\r') {
7826 PEEKC_EOB(c, p);
7827 if (c != '\n') {
7828 if (str)
7829 cstr_ccat(str, '\r');
7830 } else {
7831 file->line_num++;
7832 goto add_char;
7833 }
7834 } else {
7835 add_char:
7836 if (str)
7837 cstr_ccat(str, c);
7838 p++;
7839 }
7840 }
7841 p++;
7842 return p;
7843 }
7844
7845
7846
7847 void preprocess_skip(void)
7848 {
7849 int a, start_of_line, c;
7850 uint8_t *p;
7851
7852 p = file->buf_ptr;
7853 start_of_line = 1;
7854 a = 0;
7855 for(;;) {
7856 redo_no_start:
7857 c = *p;
7858 switch(c) {
7859 case ' ':
7860 case '\t':
7861 case '\f':
7862 case '\v':
7863 case '\r':
7864 p++;
7865 goto redo_no_start;
7866 case '\n':
7867 start_of_line = 1;
7868 file->line_num++;
7869 p++;
7870 goto redo_no_start;
7871 case '\\':
7872 file->buf_ptr = p;
7873 c = handle_eob();
7874 if (c == CH_EOF) {
7875 expect("#endif");
7876 } else if (c == '\\') {
7877
7878 = file->buf_ptr[0];
7879 handle_stray();
7880 }
7881 p = file->buf_ptr;
7882 goto redo_no_start;
7883
7884 case '\"':
7885 case '\'':
7886 p = parse_pp_string(p, c, NULL);
7887 break;
7888
7889 case '/':
7890 file->buf_ptr = p;
7891 ch = *p;
7892 minp();
7893 p = file->buf_ptr;
7894 if (ch == '*') {
7895 p = parse_comment(p);
7896 } else if (ch == '/') {
7897 p = parse_line_comment(p);
7898 }
7899 break;
7900
7901 case '#':
7902 p++;
7903 if (start_of_line) {
7904 file->buf_ptr = p;
7905 next_nomacro();
7906 p = file->buf_ptr;
7907 if (a == 0 &&
7908 (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
7909 goto the_end;
7910 if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
7911 a++;
7912 else if (tok == TOK_ENDIF)
7913 a--;
7914 }
7915 break;
7916 default:
7917 p++;
7918 break;
7919 }
7920 start_of_line = 0;
7921 }
7922 the_end: ;
7923 file->buf_ptr = p;
7924 }
7925
7926
7927
7928
7929
7930
7931
7932
7933 void save_parse_state(ParseState *s)
7934 {
7935 s->line_num = file->line_num;
7936 s->macro_ptr = macro_ptr;
7937 s->tok = tok;
7938 s->tokc = tokc;
7939 }
7940
7941
7942 void restore_parse_state(ParseState *s)
7943 {
7944 file->line_num = s->line_num;
7945 macro_ptr = s->macro_ptr;
7946 tok = s->tok;
7947 tokc = s->tokc;
7948 }
7949
7950
7951
7952 static inline int tok_ext_size(int t)
7953 {
7954 switch(t) {
7955
7956 case TOK_CINT:
7957 case TOK_CUINT:
7958 case TOK_CCHAR:
7959 case TOK_LCHAR:
7960 case TOK_CFLOAT:
7961 case TOK_LINENUM:
7962 return 1;
7963 case TOK_STR:
7964 case TOK_LSTR:
7965 case TOK_PPNUM:
7966 error("unsupported token");
7967 return 1;
7968 case TOK_CDOUBLE:
7969 case TOK_CLLONG:
7970 case TOK_CULLONG:
7971 return 2;
7972 case TOK_CLDOUBLE:
7973 return LDOUBLE_SIZE / 4;
7974 default:
7975 return 0;
7976 }
7977 }
7978
7979
7980
7981 static inline void tok_str_new(TokenString *s)
7982 {
7983 s->str = NULL;
7984 s->len = 0;
7985 s->allocated_len = 0;
7986 s->last_line_num = -1;
7987 }
7988
7989 static void tok_str_free(int *str)
7990 {
7991 tcc_free(str);
7992 }
7993
7994 static int *tok_str_realloc(TokenString *s)
7995 {
7996 int *str, len;
7997
7998 if (s->allocated_len == 0) {
7999 len = 8;
8000 } else {
8001 len = s->allocated_len * 2;
8002 }
8003 str = tcc_realloc(s->str, len * sizeof(int));
8004 if (!str)
8005 error("memory full");
8006 s->allocated_len = len;
8007 s->str = str;
8008 return str;
8009 }
8010
8011 static void tok_str_add(TokenString *s, int t)
8012 {
8013 int len, *str;
8014
8015 len = s->len;
8016 str = s->str;
8017 if (len >= s->allocated_len)
8018 str = tok_str_realloc(s);
8019 str[len++] = t;
8020 s->len = len;
8021 }
8022
8023 static void tok_str_add2(TokenString *s, int t, CValue *cv)
8024 {
8025 int len, *str;
8026
8027 len = s->len;
8028 str = s->str;
8029
8030
8031 if (len + TOK_MAX_SIZE > s->allocated_len)
8032 str = tok_str_realloc(s);
8033 str[len++] = t;
8034 switch(t) {
8035 case TOK_CINT:
8036 case TOK_CUINT:
8037 case TOK_CCHAR:
8038 case TOK_LCHAR:
8039 case TOK_CFLOAT:
8040 case TOK_LINENUM:
8041 str[len++] = cv->tab[0];
8042 break;
8043 case TOK_PPNUM:
8044 case TOK_STR:
8045 case TOK_LSTR:
8046 {
8047 int nb_words;
8048 CString *cstr;
8049
8050 nb_words = (sizeof(CString) + cv->cstr->size + 3) >> 2;
8051 while ((len + nb_words) > s->allocated_len)
8052 str = tok_str_realloc(s);
8053 cstr = (CString *)(str + len);
8054 cstr->data = NULL;
8055 cstr->size = cv->cstr->size;
8056 cstr->data_allocated = NULL;
8057 cstr->size_allocated = cstr->size;
8058 memcpy((char *)cstr + sizeof(CString),
8059 cv->cstr->data, cstr->size);
8060 len += nb_words;
8061 }
8062 break;
8063 case TOK_CDOUBLE:
8064 case TOK_CLLONG:
8065 case TOK_CULLONG:
8066 #if LDOUBLE_SIZE == 8
8067 case TOK_CLDOUBLE:
8068 #endif
8069 str[len++] = cv->tab[0];
8070 str[len++] = cv->tab[1];
8071 break;
8072 #if LDOUBLE_SIZE == 12
8073 case TOK_CLDOUBLE:
8074 str[len++] = cv->tab[0];
8075 str[len++] = cv->tab[1];
8076 str[len++] = cv->tab[2];
8077 #elif LDOUBLE_SIZE != 8
8078 #error add long double size support
8079 #endif
8080 break;
8081 default:
8082 break;
8083 }
8084 s->len = len;
8085 }
8086
8087
8088 static void tok_str_add_tok(TokenString *s)
8089 {
8090 CValue cval;
8091
8092
8093 if (file->line_num != s->last_line_num) {
8094 s->last_line_num = file->line_num;
8095 cval.i = s->last_line_num;
8096 tok_str_add2(s, TOK_LINENUM, &cval);
8097 }
8098 tok_str_add2(s, tok, &tokc);
8099 }
8100
8101 #if LDOUBLE_SIZE == 12
8102 #define LDOUBLE_GET(p, cv) \
8103 cv.tab[0] = p[0]; \
8104 cv.tab[1] = p[1]; \
8105 cv.tab[2] = p[2];
8106 #elif LDOUBLE_SIZE == 8
8107 #define LDOUBLE_GET(p, cv) \
8108 cv.tab[0] = p[0]; \
8109 cv.tab[1] = p[1];
8110 #else
8111 #error add long double size support
8112 #endif
8113
8114
8115
8116
8117 #define TOK_GET(t, p, cv) \
8118 { \
8119 t = *p++; \
8120 switch(t) { \
8121 case TOK_CINT: \
8122 case TOK_CUINT: \
8123 case TOK_CCHAR: \
8124 case TOK_LCHAR: \
8125 case TOK_CFLOAT: \
8126 case TOK_LINENUM: \
8127 cv.tab[0] = *p++; \
8128 break; \
8129 case TOK_STR: \
8130 case TOK_LSTR: \
8131 case TOK_PPNUM: \
8132 cv.cstr = (CString *)p; \
8133 cv.cstr->data = (char *)p + sizeof(CString);\
8134 p += (sizeof(CString) + cv.cstr->size + 3) >> 2;\
8135 break; \
8136 case TOK_CDOUBLE: \
8137 case TOK_CLLONG: \
8138 case TOK_CULLONG: \
8139 cv.tab[0] = p[0]; \
8140 cv.tab[1] = p[1]; \
8141 p += 2; \
8142 break; \
8143 case TOK_CLDOUBLE: \
8144 LDOUBLE_GET(p, cv); \
8145 p += LDOUBLE_SIZE / 4; \
8146 break; \
8147 default: \
8148 break; \
8149 } \
8150 }
8151
8152
8153 static inline void define_push(int v, int macro_type, int *str, Sym *first_arg)
8154 {
8155 Sym *s;
8156
8157 s = sym_push2(&define_stack, v, macro_type, (long)str);
8158 s->next = first_arg;
8159 table_ident[v - TOK_IDENT]->sym_define = s;
8160 }
8161
8162
8163 static void define_undef(Sym *s)
8164 {
8165 int v;
8166 v = s->v;
8167 if (v >= TOK_IDENT && v < tok_ident)
8168 table_ident[v - TOK_IDENT]->sym_define = NULL;
8169 s->v = 0;
8170 }
8171
8172 static inline Sym *define_find(int v)
8173 {
8174 v -= TOK_IDENT;
8175 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
8176 return NULL;
8177 return table_ident[v]->sym_define;
8178 }
8179
8180
8181 static void free_defines(Sym *b)
8182 {
8183 Sym *top, *top1;
8184 int v;
8185
8186 top = define_stack;
8187 while (top != b) {
8188 top1 = top->prev;
8189
8190 if (top->c)
8191 tok_str_free((int *)top->c);
8192 v = top->v;
8193 if (v >= TOK_IDENT && v < tok_ident)
8194 table_ident[v - TOK_IDENT]->sym_define = NULL;
8195 sym_free(top);
8196 top = top1;
8197 }
8198 define_stack = b;
8199 }
8200
8201
8202 static Sym *label_find(int v)
8203 {
8204 v -= TOK_IDENT;
8205 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
8206 return NULL;
8207 return table_ident[v]->sym_label;
8208 }
8209
8210 static Sym *label_push(Sym **ptop, int v, int flags)
8211 {
8212 Sym *s, **ps;
8213 s = sym_push2(ptop, v, 0, 0);
8214 s->r = flags;
8215 ps = &table_ident[v - TOK_IDENT]->sym_label;
8216 if (ptop == &global_label_stack) {
8217
8218
8219 while (*ps != NULL)
8220 ps = &(*ps)->prev_tok;
8221 }
8222 s->prev_tok = *ps;
8223 *ps = s;
8224 return s;
8225 }
8226
8227
8228
8229 static void label_pop(Sym **ptop, Sym *slast)
8230 {
8231 Sym *s, *s1;
8232 for(s = *ptop; s != slast; s = s1) {
8233 s1 = s->prev;
8234 if (s->r == LABEL_DECLARED) {
8235 warning("label '%s' declared but not used", get_tok_str(s->v, NULL));
8236 } else if (s->r == LABEL_FORWARD) {
8237 error("label '%s' used but not defined",
8238 get_tok_str(s->v, NULL));
8239 } else {
8240 if (s->c) {
8241
8242
8243 (s, cur_text_section, (long)s->next, 1);
8244 }
8245 }
8246
8247 [s->v - TOK_IDENT]->sym_label = s->prev_tok;
8248 sym_free(s);
8249 }
8250 *ptop = slast;
8251 }
8252
8253
8254 static int expr_preprocess(void)
8255 {
8256 int c, t;
8257 TokenString str;
8258
8259 tok_str_new(&str);
8260 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
8261 next();
8262 if (tok == TOK_DEFINED) {
8263 next_nomacro();
8264 t = tok;
8265 if (t == '(')
8266 next_nomacro();
8267 c = define_find(tok) != 0;
8268 if (t == '(')
8269 next_nomacro();
8270 tok = TOK_CINT;
8271 tokc.i = c;
8272 } else if (tok >= TOK_IDENT) {
8273
8274 = TOK_CINT;
8275 tokc.i = 0;
8276 }
8277 tok_str_add_tok(&str);
8278 }
8279 tok_str_add(&str, -1);
8280 (&str, 0);
8281
8282 = str.str;
8283 next();
8284 c = expr_const();
8285 macro_ptr = NULL;
8286 tok_str_free(str.str);
8287 return c != 0;
8288 }
8289
8290 #if defined(PARSE_DEBUG) || defined(PP_DEBUG)
8291 static void tok_print(int *str)
8292 {
8293 int t;
8294 CValue cval;
8295
8296 while (1) {
8297 TOK_GET(t, str, cval);
8298 if (!t)
8299 break;
8300 printf(" %s", get_tok_str(t, &cval));
8301 }
8302 printf("\n");
8303 }
8304 #endif
8305
8306
8307 static void parse_define(void)
8308 {
8309 Sym *s, *first, **ps;
8310 int v, t, varg, is_vaargs, c;
8311 TokenString str;
8312
8313 v = tok;
8314 if (v < TOK_IDENT)
8315 error("invalid macro name '%s'", get_tok_str(tok, &tokc));
8316
8317 = NULL;
8318 t = MACRO_OBJ;
8319
8320 = file->buf_ptr[0];
8321 if (c == '\\')
8322 c = handle_stray1(file->buf_ptr);
8323 if (c == '(') {
8324 next_nomacro();
8325 next_nomacro();
8326 ps = &first;
8327 while (tok != ')') {
8328 varg = tok;
8329 next_nomacro();
8330 is_vaargs = 0;
8331 if (varg == TOK_DOTS) {
8332 varg = TOK___VA_ARGS__;
8333 is_vaargs = 1;
8334 } else if (tok == TOK_DOTS && gnu_ext) {
8335 is_vaargs = 1;
8336 next_nomacro();
8337 }
8338 if (varg < TOK_IDENT)
8339 error("badly punctuated parameter list");
8340 s = sym_push2(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
8341 *ps = s;
8342 ps = &s->next;
8343 if (tok != ',')
8344 break;
8345 next_nomacro();
8346 }
8347 t = MACRO_FUNC;
8348 }
8349 tok_str_new(&str);
8350 next_nomacro();
8351
8352 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
8353 tok_str_add2(&str, tok, &tokc);
8354 next_nomacro();
8355 }
8356 tok_str_add(&str, 0);
8357 #ifdef PP_DEBUG
8358 printf("define %s %d: ", get_tok_str(v, NULL), t);
8359 tok_print(str.str);
8360 #endif
8361 define_push(v, t, str.str, first);
8362 }
8363
8364 static inline int hash_cached_include(int type, const char *filename)
8365 {
8366 const unsigned char *s;
8367 unsigned int h;
8368
8369 h = TOK_HASH_INIT;
8370 h = TOK_HASH_FUNC(h, type);
8371 s = filename;
8372 while (*s) {
8373 h = TOK_HASH_FUNC(h, *s);
8374 s++;
8375 }
8376 h &= (CACHED_INCLUDES_HASH_SIZE - 1);
8377 return h;
8378 }
8379
8380
8381 static CachedInclude *search_cached_include(TCCState *s1,
8382 int type, const char *filename)
8383 {
8384 CachedInclude *e;
8385 int i, h;
8386 h = hash_cached_include(type, filename);
8387 i = s1->cached_includes_hash[h];
8388 for(;;) {
8389 if (i == 0)
8390 break;
8391 e = s1->cached_includes[i - 1];
8392 if (e->type == type && !strcmp(e->filename, filename))
8393 return e;
8394 i = e->hash_next;
8395 }
8396 return NULL;
8397 }
8398
8399 static inline void add_cached_include(TCCState *s1, int type,
8400 const char *filename, int ifndef_macro)
8401 {
8402 CachedInclude *e;
8403 int h;
8404
8405 if (search_cached_include(s1, type, filename))
8406 return;
8407 #ifdef INC_DEBUG
8408 printf("adding cached '%s' %s\n", filename, get_tok_str(ifndef_macro, NULL));
8409 #endif
8410 e = tcc_malloc(sizeof(CachedInclude) + strlen(filename));
8411 if (!e)
8412 return;
8413 e->type = type;
8414 strcpy(e->filename, filename);
8415 e->ifndef_macro = ifndef_macro;
8416 dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e);
8417
8418 = hash_cached_include(type, filename);
8419 e->hash_next = s1->cached_includes_hash[h];
8420 s1->cached_includes_hash[h] = s1->nb_cached_includes;
8421 }
8422
8423 static void pragma_parse(TCCState *s1)
8424 {
8425 int val;
8426
8427 next();
8428 if (tok == TOK_pack) {
8429
8430
8431
8432
8433
8434
8435
8436 ();
8437 skip('(');
8438 if (tok == TOK_ASM_pop) {
8439 next();
8440 if (s1->pack_stack_ptr <= s1->pack_stack) {
8441 stk_error:
8442 error("out of pack stack");
8443 }
8444 s1->pack_stack_ptr--;
8445 } else {
8446 val = 0;
8447 if (tok != ')') {
8448 if (tok == TOK_ASM_push) {
8449 next();
8450 if (s1->pack_stack_ptr >= s1->pack_stack + PACK_STACK_SIZE - 1)
8451 goto stk_error;
8452 s1->pack_stack_ptr++;
8453 skip(',');
8454 }
8455 if (tok != TOK_CINT) {
8456 pack_error:
8457 error("invalid pack pragma");
8458 }
8459 val = tokc.i;
8460 if (val < 1 || val > 16 || (val & (val - 1)) != 0)
8461 goto pack_error;
8462 next();
8463 }
8464 *s1->pack_stack_ptr = val;
8465 skip(')');
8466 }
8467 }
8468 }
8469
8470
8471 static void preprocess(int is_bof)
8472 {
8473 TCCState *s1 = tcc_state;
8474 int size, i, c, n, saved_parse_flags;
8475 char buf[1024], *q, *p;
8476 char buf1[1024];
8477 BufferedFile *f;
8478 Sym *s;
8479 CachedInclude *e;
8480
8481 saved_parse_flags = parse_flags;
8482 parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM |
8483 PARSE_FLAG_LINEFEED;
8484 next_nomacro();
8485 redo:
8486 switch(tok) {
8487 case TOK_DEFINE:
8488 next_nomacro();
8489 parse_define();
8490 break;
8491 case TOK_UNDEF:
8492 next_nomacro();
8493 s = define_find(tok);
8494
8495 if (s)
8496 define_undef(s);
8497 break;
8498 case TOK_INCLUDE:
8499 case TOK_INCLUDE_NEXT:
8500 ch = file->buf_ptr[0];
8501
8502 ();
8503 if (ch == '<') {
8504 c = '>';
8505 goto read_name;
8506 } else if (ch == '\"') {
8507 c = ch;
8508 read_name:
8509
8510 ();
8511 q = buf;
8512 while (ch != c && ch != '\n' && ch != CH_EOF) {
8513 if ((q - buf) < sizeof(buf) - 1)
8514 *q++ = ch;
8515 minp();
8516 }
8517 *q = '\0';
8518 minp();
8519 #if 0
8520
8521
8522 while (ch1 != '\n' && ch1 != CH_EOF)
8523 inp();
8524 #endif
8525 } else {
8526
8527
8528 ();
8529 buf[0] = '\0';
8530 if (tok == TOK_STR) {
8531 while (tok != TOK_LINEFEED) {
8532 if (tok != TOK_STR) {
8533 include_syntax:
8534 error("'#include' expects \"FILENAME\" or <FILENAME>");
8535 }
8536 pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data);
8537 next();
8538 }
8539 c = '\"';
8540 } else {
8541 int len;
8542 while (tok != TOK_LINEFEED) {
8543 pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
8544 next();
8545 }
8546 len = strlen(buf);
8547
8548 if (len < 2 || buf[0] != '<' || buf[len - 1] != '>')
8549 goto include_syntax;
8550 memmove(buf, buf + 1, len - 2);
8551 buf[len - 2] = '\0';
8552 c = '>';
8553 }
8554 }
8555
8556 e = search_cached_include(s1, c, buf);
8557 if (e && define_find(e->ifndef_macro)) {
8558
8559
8560 #ifdef INC_DEBUG
8561 printf("%s: skipping %s\n", file->filename, buf);
8562 #endif
8563 } else {
8564 if (c == '\"') {
8565
8566 = 0;
8567 p = strrchr(file->filename, '/');
8568 if (p)
8569 size = p + 1 - file->filename;
8570 if (size > sizeof(buf1) - 1)
8571 size = sizeof(buf1) - 1;
8572 memcpy(buf1, file->filename, size);
8573 buf1[size] = '\0';
8574 pstrcat(buf1, sizeof(buf1), buf);
8575 f = tcc_open(s1, buf1);
8576 if (f) {
8577 if (tok == TOK_INCLUDE_NEXT)
8578 tok = TOK_INCLUDE;
8579 else
8580 goto found;
8581 }
8582 }
8583 if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
8584 error("#include recursion too deep");
8585
8586 = s1->nb_include_paths + s1->nb_sysinclude_paths;
8587 for(i = 0; i < n; i++) {
8588 const char *path;
8589 if (i < s1->nb_include_paths)
8590 path = s1->include_paths[i];
8591 else
8592 path = s1->sysinclude_paths[i - s1->nb_include_paths];
8593 pstrcpy(buf1, sizeof(buf1), path);
8594 pstrcat(buf1, sizeof(buf1), "/");
8595 pstrcat(buf1, sizeof(buf1), buf);
8596 f = tcc_open(s1, buf1);
8597 if (f) {
8598 if (tok == TOK_INCLUDE_NEXT)
8599 tok = TOK_INCLUDE;
8600 else
8601 goto found;
8602 }
8603 }
8604 error("include file '%s' not found", buf);
8605 f = NULL;
8606 found:
8607 #ifdef INC_DEBUG
8608 printf("%s: including %s\n", file->filename, buf1);
8609 #endif
8610 f->inc_type = c;
8611 pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf);
8612
8613
8614 *s1->include_stack_ptr++ = file;
8615 file = f;
8616
8617 if (do_debug) {
8618 put_stabs(file->filename, N_BINCL, 0, 0, 0);
8619 }
8620 tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL;
8621 ch = file->buf_ptr[0];
8622 goto the_end;
8623 }
8624 break;
8625 case TOK_IFNDEF:
8626 c = 1;
8627 goto do_ifdef;
8628 case TOK_IF:
8629 c = expr_preprocess();
8630 goto do_if;
8631 case TOK_IFDEF:
8632 c = 0;
8633 do_ifdef:
8634 next_nomacro();
8635 if (tok < TOK_IDENT)
8636 error("invalid argument for '#if%sdef'", c ? "n" : "");
8637 if (is_bof) {
8638 if (c) {
8639 #ifdef INC_DEBUG
8640 printf("#ifndef %s\n", get_tok_str(tok, NULL));
8641 #endif
8642 file->ifndef_macro = tok;
8643 }
8644 }
8645 c = (define_find(tok) != 0) ^ c;
8646 do_if:
8647 if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
8648 error("memory full");
8649 *s1->ifdef_stack_ptr++ = c;
8650 goto test_skip;
8651 case TOK_ELSE:
8652 if (s1->ifdef_stack_ptr == s1->ifdef_stack)
8653 error("#else without matching #if");
8654 if (s1->ifdef_stack_ptr[-1] & 2)
8655 error("#else after #else");
8656 c = (s1->ifdef_stack_ptr[-1] ^= 3);
8657 goto test_skip;
8658 case TOK_ELIF:
8659 if (s1->ifdef_stack_ptr == s1->ifdef_stack)
8660 error("#elif without matching #if");
8661 c = s1->ifdef_stack_ptr[-1];
8662 if (c > 1)
8663 error("#elif after #else");
8664
8665 if (c == 1)
8666 goto skip;
8667 c = expr_preprocess();
8668 s1->ifdef_stack_ptr[-1] = c;
8669 test_skip:
8670 if (!(c & 1)) {
8671 skip:
8672 preprocess_skip();
8673 is_bof = 0;
8674 goto redo;
8675 }
8676 break;
8677 case TOK_ENDIF:
8678 if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr)
8679 error("#endif without matching #if");
8680 s1->ifdef_stack_ptr--;
8681
8682
8683 if (file->ifndef_macro &&
8684 s1->ifdef_stack_ptr == file->ifdef_stack_ptr) {
8685 file->ifndef_macro_saved = file->ifndef_macro;
8686
8687
8688 ->ifndef_macro = 0;
8689 while (tok != TOK_LINEFEED)
8690 next_nomacro();
8691 tok_flags |= TOK_FLAG_ENDIF;
8692 goto the_end;
8693 }
8694 break;
8695 case TOK_LINE:
8696 next();
8697 if (tok != TOK_CINT)
8698 error("#line");
8699 file->line_num = tokc.i - 1;
8700 ();
8701 if (tok != TOK_LINEFEED) {
8702 if (tok != TOK_STR)
8703 error("#line");
8704 pstrcpy(file->filename, sizeof(file->filename),
8705 (char *)tokc.cstr->data);
8706 }
8707 break;
8708 case TOK_ERROR:
8709 case TOK_WARNING:
8710 c = tok;
8711 ch = file->buf_ptr[0];
8712 skip_spaces();
8713 q = buf;
8714 while (ch != '\n' && ch != CH_EOF) {
8715 if ((q - buf) < sizeof(buf) - 1)
8716 *q++ = ch;
8717 minp();
8718 }
8719 *q = '\0';
8720 if (c == TOK_ERROR)
8721 error("#error %s", buf);
8722 else
8723 warning("#warning %s", buf);
8724 break;
8725 case TOK_PRAGMA:
8726 pragma_parse(s1);
8727 break;
8728 default:
8729 if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_CINT) {
8730
8731
8732 } else {
8733 if (!(saved_parse_flags & PARSE_FLAG_ASM_COMMENTS))
8734 error("invalid preprocessing directive #%s", get_tok_str(tok, &tokc));
8735 }
8736 break;
8737 }
8738
8739 while (tok != TOK_LINEFEED)
8740 next_nomacro();
8741 the_end:
8742 parse_flags = saved_parse_flags;
8743 }
8744
8745
8746 static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long)
8747 {
8748 int c, n;
8749 const uint8_t *p;
8750
8751 p = buf;
8752 for(;;) {
8753 c = *p;
8754 if (c == '\0')
8755 break;
8756 if (c == '\\') {
8757 p++;
8758
8759 = *p;
8760 switch(c) {
8761 case '0': case '1': case '2': case '3':
8762 case '4': case '5': case '6': case '7':
8763
8764 = c - '0';
8765 p++;
8766 c = *p;
8767 if (isoct(c)) {
8768 n = n * 8 + c - '0';
8769 p++;
8770 c = *p;
8771 if (isoct(c)) {
8772 n = n * 8 + c - '0';
8773 p++;
8774 }
8775 }
8776 c = n;
8777 goto add_char_nonext;
8778 case 'x':
8779 p++;
8780 n = 0;
8781 for(;;) {
8782 c = *p;
8783 if (c >= 'a' && c <= 'f')
8784 c = c - 'a' + 10;
8785 else if (c >= 'A' && c <= 'F')
8786 c = c - 'A' + 10;
8787 else if (isnum(c))
8788 c = c - '0';
8789 else
8790 break;
8791 n = n * 16 + c;
8792 p++;
8793 }
8794 c = n;
8795 goto add_char_nonext;
8796 case 'a':
8797 c = '\a';
8798 break;
8799 case 'b':
8800 c = '\b';
8801 break;
8802 case 'f':
8803 c = '\f';
8804 break;
8805 case 'n':
8806 c = '\n';
8807 break;
8808 case 'r':
8809 c = '\r';
8810 break;
8811 case 't':
8812 c = '\t';
8813 break;
8814 case 'v':
8815 c = '\v';
8816 break;
8817 case 'e':
8818 if (!gnu_ext)
8819 goto invalid_escape;
8820 c = 27;
8821 break;
8822 case '\'':
8823 case '\"':
8824 case '\\':
8825 case '?':
8826 break;
8827 default:
8828 invalid_escape:
8829 if (c >= '!' && c <= '~')
8830 warning("unknown escape sequence: \'\\%c\'", c);
8831 else
8832 warning("unknown escape sequence: \'\\x%x\'", c);
8833 break;
8834 }
8835 }
8836 p++;
8837 add_char_nonext:
8838 if (!is_long)
8839 cstr_ccat(outstr, c);
8840 else
8841 cstr_wccat(outstr, c);
8842 }
8843
8844 if (!is_long)
8845 cstr_ccat(outstr, '\0');
8846 else
8847 cstr_wccat(outstr, '\0');
8848 }
8849
8850
8851 #define BN_SIZE 2
8852
8853
8854 void bn_lshift(unsigned int *bn, int shift, int or_val)
8855 {
8856 int i;
8857 unsigned int v;
8858 for(i=0;i<BN_SIZE;i++) {
8859 v = bn[i];
8860 bn[i] = (v << shift) | or_val;
8861 or_val = v >> (32 - shift);
8862 }
8863 }
8864
8865 void bn_zero(unsigned int *bn)
8866 {
8867 int i;
8868 for(i=0;i<BN_SIZE;i++) {
8869 bn[i] = 0;
8870 }
8871 }
8872
8873
8874
8875 void parse_number(const char *p)
8876 {
8877 int b, t, shift, frac_bits, s, exp_val, ch;
8878 char *q;
8879 unsigned int bn[BN_SIZE];
8880 double d;
8881
8882
8883 = token_buf;
8884 ch = *p++;
8885 t = ch;
8886 ch = *p++;
8887 *q++ = t;
8888 b = 10;
8889 if (t == '.') {
8890 goto float_frac_parse;
8891 } else if (t == '0') {
8892 if (ch == 'x' || ch == 'X') {
8893 q--;
8894 ch = *p++;
8895 b = 16;
8896 } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
8897 q--;
8898 ch = *p++;
8899 b = 2;
8900 }
8901 }
8902
8903
8904 while (1) {
8905 if (ch >= 'a' && ch <= 'f')
8906 t = ch - 'a' + 10;
8907 else if (ch >= 'A' && ch <= 'F')
8908 t = ch - 'A' + 10;
8909 else if (isnum(ch))
8910 t = ch - '0';
8911 else
8912 break;
8913 if (t >= b)
8914 break;
8915 if (q >= token_buf + STRING_MAX_SIZE) {
8916 num_too_long:
8917 error("number too long");
8918 }
8919 *q++ = ch;
8920 ch = *p++;
8921 }
8922 if (ch == '.' ||
8923 ((ch == 'e' || ch == 'E') && b == 10) ||
8924 ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
8925 if (b != 10) {
8926
8927
8928
8929
8930
8931 *q = '\0';
8932 if (b == 16)
8933 shift = 4;
8934 else
8935 shift = 2;
8936 bn_zero(bn);
8937 q = token_buf;
8938 while (1) {
8939 t = *q++;
8940 if (t == '\0') {
8941 break;
8942 } else if (t >= 'a') {
8943 t = t - 'a' + 10;
8944 } else if (t >= 'A') {
8945 t = t - 'A' + 10;
8946 } else {
8947 t = t - '0';
8948 }
8949 bn_lshift(bn, shift, t);
8950 }
8951 frac_bits = 0;
8952 if (ch == '.') {
8953 ch = *p++;
8954 while (1) {
8955 t = ch;
8956 if (t >= 'a' && t <= 'f') {
8957 t = t - 'a' + 10;
8958 } else if (t >= 'A' && t <= 'F') {
8959 t = t - 'A' + 10;
8960 } else if (t >= '0' && t <= '9') {
8961 t = t - '0';
8962 } else {
8963 break;
8964 }
8965 if (t >= b)
8966 error("invalid digit");
8967 bn_lshift(bn, shift, t);
8968 frac_bits += shift;
8969 ch = *p++;
8970 }
8971 }
8972 if (ch != 'p' && ch != 'P')
8973 expect("exponent");
8974 ch = *p++;
8975 s = 1;
8976 exp_val = 0;
8977 if (ch == '+') {
8978 ch = *p++;
8979 } else if (ch == '-') {
8980 s = -1;
8981 ch = *p++;
8982 }
8983 if (ch < '0' || ch > '9')
8984 expect("exponent digits");
8985 while (ch >= '0' && ch <= '9') {
8986 exp_val = exp_val * 10 + ch - '0';
8987 ch = *p++;
8988 }
8989 exp_val = exp_val * s;
8990
8991
8992
8993 = (double)bn[1] * 4294967296.0 + (double)bn[0];
8994 d = ldexp(d, exp_val - frac_bits);
8995 t = toup(ch);
8996 if (t == 'F') {
8997 ch = *p++;
8998 tok = TOK_CFLOAT;
8999
9000 .f = (float)d;
9001 } else if (t == 'L') {
9002 ch = *p++;
9003 tok = TOK_CLDOUBLE;
9004
9005 .ld = (long double)d;
9006 } else {
9007 tok = TOK_CDOUBLE;
9008 tokc.d = d;
9009 }
9010 } else {
9011
9012 if (ch == '.') {
9013 if (q >= token_buf + STRING_MAX_SIZE)
9014 goto num_too_long;
9015 *q++ = ch;
9016 ch = *p++;
9017 float_frac_parse:
9018 while (ch >= '0' && ch <= '9') {
9019 if (q >= token_buf + STRING_MAX_SIZE)
9020 goto num_too_long;
9021 *q++ = ch;
9022 ch = *p++;
9023 }
9024 }
9025 if (ch == 'e' || ch == 'E') {
9026 if (q >= token_buf + STRING_MAX_SIZE)
9027 goto num_too_long;
9028 *q++ = ch;
9029 ch = *p++;
9030 if (ch == '-' || ch == '+') {
9031 if (q >= token_buf + STRING_MAX_SIZE)
9032 goto num_too_long;
9033 *q++ = ch;
9034 ch = *p++;
9035 }
9036 if (ch < '0' || ch > '9')
9037 expect("exponent digits");
9038 while (ch >= '0' && ch <= '9') {
9039 if (q >= token_buf + STRING_MAX_SIZE)
9040 goto num_too_long;
9041 *q++ = ch;
9042 ch = *p++;
9043 }
9044 }
9045 *q = '\0';
9046 t = toup(ch);
9047 errno = 0;
9048 if (t == 'F') {
9049 ch = *p++;
9050 tok = TOK_CFLOAT;
9051 tokc.f = strtof(token_buf, NULL);
9052 } else if (t == 'L') {
9053 ch = *p++;
9054 tok = TOK_CLDOUBLE;
9055 tokc.ld = strtold(token_buf, NULL);
9056 } else {
9057 tok = TOK_CDOUBLE;
9058 tokc.d = strtod(token_buf, NULL);
9059 }
9060 }
9061 } else {
9062 unsigned long long n, n1;
9063 int lcount, ucount;
9064
9065
9066 *q = '\0';
9067 q = token_buf;
9068 if (b == 10 && *q == '0') {
9069 b = 8;
9070 q++;
9071 }
9072 n = 0;
9073 while(1) {
9074 t = *q++;
9075
9076 if (t == '\0') {
9077 break;
9078 } else if (t >= 'a') {
9079 t = t - 'a' + 10;
9080 } else if (t >= 'A') {
9081 t = t - 'A' + 10;
9082 } else {
9083 t = t - '0';
9084 if (t >= b)
9085 error("invalid digit");
9086 }
9087 n1 = n;
9088 n = n * b + t;
9089
9090
9091 if (n < n1)
9092 error("integer constant overflow");
9093 }
9094
9095
9096 if ((n & 0xffffffff00000000LL) != 0) {
9097 if ((n >> 63) != 0)
9098 tok = TOK_CULLONG;
9099 else
9100 tok = TOK_CLLONG;
9101 } else if (n > 0x7fffffff) {
9102 tok = TOK_CUINT;
9103 } else {
9104 tok = TOK_CINT;
9105 }
9106 lcount = 0;
9107 ucount = 0;
9108 for(;;) {
9109 t = toup(ch);
9110 if (t == 'L') {
9111 if (lcount >= 2)
9112 error("three 'l's in integer constant");
9113 lcount++;
9114 if (lcount == 2) {
9115 if (tok == TOK_CINT)
9116 tok = TOK_CLLONG;
9117 else if (tok == TOK_CUINT)
9118 tok = TOK_CULLONG;
9119 }
9120 ch = *p++;
9121 } else if (t == 'U') {
9122 if (ucount >= 1)
9123 error("two 'u's in integer constant");
9124 ucount++;
9125 if (tok == TOK_CINT)
9126 tok = TOK_CUINT;
9127 else if (tok == TOK_CLLONG)
9128 tok = TOK_CULLONG;
9129 ch = *p++;
9130 } else {
9131 break;
9132 }
9133 }
9134 if (tok == TOK_CINT || tok == TOK_CUINT)
9135 tokc.ui = n;
9136 else
9137 tokc.ull = n;
9138 }
9139 }
9140
9141
9142 #define PARSE2(c1, tok1, c2, tok2) \
9143 case c1: \
9144 PEEKC(c, p); \
9145 if (c == c2) { \
9146 p++; \
9147 tok = tok2; \
9148 } else { \
9149 tok = tok1; \
9150 } \
9151 break;
9152
9153
9154 static void next_nomacro1(void)
9155 {
9156 int t, c, is_long;
9157 TokenSym *ts;
9158 uint8_t *p, *p1;
9159 unsigned int h;
9160
9161 p = file->buf_ptr;
9162 redo_no_start:
9163 c = *p;
9164 switch(c) {
9165 case ' ':
9166 case '\t':
9167 case '\f':
9168 case '\v':
9169 case '\r':
9170 p++;
9171 goto redo_no_start;
9172
9173 case '\\':
9174
9175 if (p >= file->buf_end) {
9176 file->buf_ptr = p;
9177 handle_eob();
9178 p = file->buf_ptr;
9179 if (p >= file->buf_end)
9180 goto parse_eof;
9181 else
9182 goto redo_no_start;
9183 } else {
9184 file->buf_ptr = p;
9185 ch = *p;
9186 handle_stray();
9187 p = file->buf_ptr;
9188 goto redo_no_start;
9189 }
9190 parse_eof:
9191 {
9192 TCCState *s1 = tcc_state;
9193 if (parse_flags & PARSE_FLAG_LINEFEED) {
9194 tok = TOK_LINEFEED;
9195 } else if (s1->include_stack_ptr == s1->include_stack ||
9196 !(parse_flags & PARSE_FLAG_PREPROCESS)) {
9197
9198 = TOK_EOF;
9199 } else {
9200
9201
9202
9203
9204 if (tok_flags & TOK_FLAG_ENDIF) {
9205 #ifdef INC_DEBUG
9206 printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL));
9207 #endif
9208 add_cached_include(s1, file->inc_type, file->inc_filename,
9209 file->ifndef_macro_saved);
9210 }
9211
9212
9213 if (do_debug) {
9214 put_stabd(N_EINCL, 0, 0);
9215 }
9216
9217 (file);
9218 s1->include_stack_ptr--;
9219 file = *s1->include_stack_ptr;
9220 p = file->buf_ptr;
9221 goto redo_no_start;
9222 }
9223 }
9224 break;
9225
9226 case '\n':
9227 if (parse_flags & PARSE_FLAG_LINEFEED) {
9228 tok = TOK_LINEFEED;
9229 } else {
9230 file->line_num++;
9231 tok_flags |= TOK_FLAG_BOL;
9232 p++;
9233 goto redo_no_start;
9234 }
9235 break;
9236
9237 case '#':
9238
9239 (c, p);
9240 if ((tok_flags & TOK_FLAG_BOL) &&
9241 (parse_flags & PARSE_FLAG_PREPROCESS)) {
9242 file->buf_ptr = p;
9243 preprocess(tok_flags & TOK_FLAG_BOF);
9244 p = file->buf_ptr;
9245 goto redo_no_start;
9246 } else {
9247 if (c == '#') {
9248 p++;
9249 tok = TOK_TWOSHARPS;
9250 } else {
9251 if (parse_flags & PARSE_FLAG_ASM_COMMENTS) {
9252 p = parse_line_comment(p - 1);
9253 goto redo_no_start;
9254 } else {
9255 tok = '#';
9256 }
9257 }
9258 }
9259 break;
9260
9261 case 'a': case 'b': case 'c': case 'd':
9262 case 'e': case 'f': case 'g': case 'h':
9263 case 'i': case 'j': case 'k': case 'l':
9264 case 'm': case 'n': case 'o': case 'p':
9265 case 'q': case 'r': case 's': case 't':
9266 case 'u': case 'v': case 'w': case 'x':
9267 case 'y': case 'z':
9268 case 'A': case 'B': case 'C': case 'D':
9269 case 'E': case 'F': case 'G': case 'H':
9270 case 'I': case 'J': case 'K':
9271 case 'M': case 'N': case 'O': case 'P':
9272 case 'Q': case 'R': case 'S': case 'T':
9273 case 'U': case 'V': case 'W': case 'X':
9274 case 'Y': case 'Z':
9275 case '_':
9276 parse_ident_fast:
9277 p1 = p;
9278 h = TOK_HASH_INIT;
9279 h = TOK_HASH_FUNC(h, c);
9280 p++;
9281 for(;;) {
9282 c = *p;
9283 if (!isidnum_table[c])
9284 break;
9285 h = TOK_HASH_FUNC(h, c);
9286 p++;
9287 }
9288 if (c != '\\') {
9289 TokenSym **pts;
9290 int len;
9291
9292
9293
9294 = p - p1;
9295 h &= (TOK_HASH_SIZE - 1);
9296 pts = &hash_ident[h];
9297 for(;;) {
9298 ts = *pts;
9299 if (!ts)
9300 break;
9301 if (ts->len == len && !memcmp(ts->str, p1, len))
9302 goto token_found;
9303 pts = &(ts->hash_next);
9304 }
9305 ts = tok_alloc_new(pts, p1, len);
9306 token_found: ;
9307 } else {
9308
9309 (&tokcstr);
9310
9311 while (p1 < p) {
9312 cstr_ccat(&tokcstr, *p1);
9313 p1++;
9314 }
9315 p--;
9316 PEEKC(c, p);
9317 parse_ident_slow:
9318 while (isidnum_table[c]) {
9319 cstr_ccat(&tokcstr, c);
9320 PEEKC(c, p);
9321 }
9322 ts = tok_alloc(tokcstr.data, tokcstr.size);
9323 }
9324 tok = ts->tok;
9325 break;
9326 case 'L':
9327 t = p[1];
9328 if (t != '\\' && t != '\'' && t != '\"') {
9329
9330 goto parse_ident_fast;
9331 } else {
9332 PEEKC(c, p);
9333 if (c == '\'' || c == '\"') {
9334 is_long = 1;
9335 goto str_const;
9336 } else {
9337 cstr_reset(&tokcstr);
9338 cstr_ccat(&tokcstr, 'L');
9339 goto parse_ident_slow;
9340 }
9341 }
9342 break;
9343 case '0': case '1': case '2': case '3':
9344 case '4': case '5': case '6': case '7':
9345 case '8': case '9':
9346
9347 cstr_reset(&tokcstr);
9348
9349
9350 parse_num:
9351 for(;;) {
9352 t = c;
9353 cstr_ccat(&tokcstr, c);
9354 PEEKC(c, p);
9355 if (!(isnum(c) || isid(c) || c == '.' ||
9356 ((c == '+' || c == '-') &&
9357 (t == 'e' || t == 'E' || t == 'p' || t == 'P'))))
9358 break;
9359 }
9360
9361 (&tokcstr, '\0');
9362 tokc.cstr = &tokcstr;
9363 tok = TOK_PPNUM;
9364 break;
9365 case '.':
9366
9367 (c, p);
9368 if (isnum(c)) {
9369 cstr_reset(&tokcstr);
9370 cstr_ccat(&tokcstr, '.');
9371 goto parse_num;
9372 } else if (c == '.') {
9373 PEEKC(c, p);
9374 if (c != '.')
9375 expect("'.'");
9376 PEEKC(c, p);
9377 tok = TOK_DOTS;
9378 } else {
9379 tok = '.';
9380 }
9381 break;
9382 case '\'':
9383 case '\"':
9384 is_long = 0;
9385 str_const:
9386 {
9387 CString str;
9388 int sep;
9389
9390 sep = c;
9391
9392
9393 (&str);
9394 p = parse_pp_string(p, sep, &str);
9395 cstr_ccat(&str, '\0');
9396
9397
9398 (&tokcstr);
9399 parse_escape_string(&tokcstr, str.data, is_long);
9400 cstr_free(&str);
9401
9402 if (sep == '\'') {
9403 int char_size;
9404
9405 if (!is_long)
9406 char_size = 1;
9407 else
9408 char_size = sizeof(int);
9409 if (tokcstr.size <= char_size)
9410 error("empty character constant");
9411 if (tokcstr.size > 2 * char_size)
9412 warning("multi-character character constant");
9413 if (!is_long) {
9414 tokc.i = *(int8_t *)tokcstr.data;
9415 tok = TOK_CCHAR;
9416 } else {
9417 tokc.i = *(int *)tokcstr.data;
9418 tok = TOK_LCHAR;
9419 }
9420 } else {
9421 tokc.cstr = &tokcstr;
9422 if (!is_long)
9423 tok = TOK_STR;
9424 else
9425 tok = TOK_LSTR;
9426 }
9427 }
9428 break;
9429
9430 case '<':
9431 PEEKC(c, p);
9432 if (c == '=') {
9433 p++;
9434 tok = TOK_LE;
9435 } else if (c == '<') {
9436 PEEKC(c, p);
9437 if (c == '=') {
9438 p++;
9439 tok = TOK_A_SHL;
9440 } else {
9441 tok = TOK_SHL;
9442 }
9443 } else {
9444 tok = TOK_LT;
9445 }
9446 break;
9447
9448 case '>':
9449 PEEKC(c, p);
9450 if (c == '=') {
9451 p++;
9452 tok = TOK_GE;
9453 } else if (c == '>') {
9454 PEEKC(c, p);
9455 if (c == '=') {
9456 p++;
9457 tok = TOK_A_SAR;
9458 } else {
9459 tok = TOK_SAR;
9460 }
9461 } else {
9462 tok = TOK_GT;
9463 }
9464 break;
9465
9466 case '&':
9467 PEEKC(c, p);
9468 if (c == '&') {
9469 p++;
9470 tok = TOK_LAND;
9471 } else if (c == '=') {
9472 p++;
9473 tok = TOK_A_AND;
9474 } else {
9475 tok = '&';
9476 }
9477 break;
9478
9479 case '|':
9480 PEEKC(c, p);
9481 if (c == '|') {
9482 p++;
9483 tok = TOK_LOR;
9484 } else if (c == '=') {
9485 p++;
9486 tok = TOK_A_OR;
9487 } else {
9488 tok = '|';
9489 }
9490 break;
9491
9492 case '+':
9493 PEEKC(c, p);
9494 if (c == '+') {
9495 p++;
9496 tok = TOK_INC;
9497 } else if (c == '=') {
9498 p++;
9499 tok = TOK_A_ADD;
9500 } else {
9501 tok = '+';
9502 }
9503 break;
9504
9505 case '-':
9506 PEEKC(c, p);
9507 if (c == '-') {
9508 p++;
9509 tok = TOK_DEC;
9510 } else if (c == '=') {
9511 p++;
9512 tok = TOK_A_SUB;
9513 } else if (c == '>') {
9514 p++;
9515 tok = TOK_ARROW;
9516 } else {
9517 tok = '-';
9518 }
9519 break;
9520
9521 PARSE2('!', '!', '=', TOK_NE)
9522 PARSE2('=', '=', '=', TOK_EQ)
9523 PARSE2('*', '*', '=', TOK_A_MUL)
9524 PARSE2('%', '%', '=', TOK_A_MOD)
9525 PARSE2('^', '^', '=', TOK_A_XOR)
9526
9527
9528 case '/':
9529 PEEKC(c, p);
9530 if (c == '*') {
9531 p = parse_comment(p);
9532 goto redo_no_start;
9533 } else if (c == '/') {
9534 p = parse_line_comment(p);
9535 goto redo_no_start;
9536 } else if (c == '=') {
9537 p++;
9538 tok = TOK_A_DIV;
9539 } else {
9540 tok = '/';
9541 }
9542 break;
9543
9544
9545 case '(':
9546 case ')':
9547 case '[':
9548 case ']':
9549 case '{':
9550 case '}':
9551 case ',':
9552 case ';':
9553 case ':':
9554 case '?':
9555 case '~':
9556 case '$':
9557 case '@':
9558 = c;
9559 p++;
9560 break;
9561 default:
9562 error("unrecognized character \\x%02x", c);
9563 break;
9564 }
9565 file->buf_ptr = p;
9566 tok_flags = 0;
9567 #if defined(PARSE_DEBUG)
9568 printf("token = %s\n", get_tok_str(tok, &tokc));
9569 #endif
9570 }
9571
9572
9573
9574 static void next_nomacro(void)
9575 {
9576 if (macro_ptr) {
9577 redo:
9578 tok = *macro_ptr;
9579 if (tok) {
9580 TOK_GET(tok, macro_ptr, tokc);
9581 if (tok == TOK_LINENUM) {
9582 file->line_num = tokc.i;
9583 goto redo;
9584 }
9585 }
9586 } else {
9587 next_nomacro1();
9588 }
9589 }
9590
9591
9592 static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
9593 {
9594 int *st, last_tok, t, notfirst;
9595 Sym *s;
9596 CValue cval;
9597 TokenString str;
9598 CString cstr;
9599
9600 tok_str_new(&str);
9601 last_tok = 0;
9602 while(1) {
9603 TOK_GET(t, macro_str, cval);
9604 if (!t)
9605 break;
9606 if (t == '#') {
9607
9608 (t, macro_str, cval);
9609 if (!t)
9610 break;
9611 s = sym_find2(args, t);
9612 if (s) {
9613 cstr_new(&cstr);
9614 st = (int *)s->c;
9615 notfirst = 0;
9616 while (*st) {
9617 if (notfirst)
9618 cstr_ccat(&cstr, ' ');
9619 TOK_GET(t, st, cval);
9620 cstr_cat(&cstr, get_tok_str(t, &cval));
9621 notfirst = 1;
9622 }
9623 cstr_ccat(&cstr, '\0');
9624 #ifdef PP_DEBUG
9625 printf("stringize: %s\n", (char *)cstr.data);
9626 #endif
9627
9628 .cstr = &cstr;
9629 tok_str_add2(&str, TOK_STR, &cval);
9630 cstr_free(&cstr);
9631 } else {
9632 tok_str_add2(&str, t, &cval);
9633 }
9634 } else if (t >= TOK_IDENT) {
9635 s = sym_find2(args, t);
9636 if (s) {
9637 st = (int *)s->c;
9638
9639 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
9640
9641
9642
9643
9644
9645 if (gnu_ext && s->type.t &&
9646 last_tok == TOK_TWOSHARPS &&
9647 str.len >= 2 && str.str[str.len - 2] == ',') {
9648 if (*st == 0) {
9649
9650 .len -= 2;
9651 } else {
9652
9653 .len--;
9654 goto add_var;
9655 }
9656 } else {
9657 int t1;
9658 add_var:
9659 for(;;) {
9660 TOK_GET(t1, st, cval);
9661 if (!t1)
9662 break;
9663 tok_str_add2(&str, t1, &cval);
9664 }
9665 }
9666 } else {
9667
9668
9669 (&str, nested_list, st, NULL);
9670 }
9671 } else {
9672 tok_str_add(&str, t);
9673 }
9674 } else {
9675 tok_str_add2(&str, t, &cval);
9676 }
9677 last_tok = t;
9678 }
9679 tok_str_add(&str, 0);
9680 return str.str;
9681 }
9682
9683 static char const ab_month_name[12][4] =
9684 {
9685 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
9686 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
9687 };
9688
9689
9690
9691
9692
9693 static int macro_subst_tok(TokenString *tok_str,
9694 Sym **nested_list, Sym *s, struct macro_level **can_read_stream)
9695 {
9696 Sym *args, *sa, *sa1;
9697 int mstr_allocated, parlevel, *mstr, t, t1;
9698 TokenString str;
9699 char *cstrval;
9700 CValue cval;
9701 CString cstr;
9702 char buf[32];
9703
9704
9705
9706 if (tok == TOK___LINE__) {
9707 snprintf(buf, sizeof(buf), "%d", file->line_num);
9708 cstrval = buf;
9709 t1 = TOK_PPNUM;
9710 goto add_cstr1;
9711 } else if (tok == TOK___FILE__) {
9712 cstrval = file->filename;
9713 goto add_cstr;
9714 } else if (tok == TOK___DATE__ || tok == TOK___TIME__) {
9715 time_t ti;
9716 struct tm *tm;
9717
9718 time(&ti);
9719 tm = localtime(&ti);
9720 if (tok == TOK___DATE__) {
9721 snprintf(buf, sizeof(buf), "%s %2d %d",
9722 ab_month_name[tm->tm_mon], tm->tm_mday, tm->tm_year + 1900);
9723 } else {
9724 snprintf(buf, sizeof(buf), "%02d:%02d:%02d",
9725 tm->tm_hour, tm->tm_min, tm->tm_sec);
9726 }
9727 cstrval = buf;
9728 add_cstr:
9729 t1 = TOK_STR;
9730 add_cstr1:
9731 cstr_new(&cstr);
9732 cstr_cat(&cstr, cstrval);
9733 cstr_ccat(&cstr, '\0');
9734 cval.cstr = &cstr;
9735 tok_str_add2(tok_str, t1, &cval);
9736 cstr_free(&cstr);
9737 } else {
9738 mstr = (int *)s->c;
9739 mstr_allocated = 0;
9740 if (s->type.t == MACRO_FUNC) {
9741
9742
9743 redo:
9744 if (macro_ptr) {
9745 t = *macro_ptr;
9746 if (t == 0 && can_read_stream) {
9747
9748
9749 struct macro_level *ml = *can_read_stream;
9750 macro_ptr = NULL;
9751 if (ml)
9752 {
9753 macro_ptr = ml->p;
9754 ml->p = NULL;
9755 *can_read_stream = ml -> prev;
9756 }
9757 goto redo;
9758 }
9759 } else {
9760
9761 = file->buf_ptr[0];
9762 while (is_space(ch) || ch == '\n')
9763 cinp();
9764 t = ch;
9765 }
9766 if (t != '(')
9767 return -1;
9768
9769
9770 ();
9771 next_nomacro();
9772 args = NULL;
9773 sa = s->next;
9774
9775 for(;;) {
9776
9777 if (!args && !sa && tok == ')')
9778 break;
9779 if (!sa)
9780 error("macro '%s' used with too many args",
9781 get_tok_str(s->v, 0));
9782 tok_str_new(&str);
9783 parlevel = 0;
9784
9785 while ((parlevel > 0 ||
9786 (tok != ')' &&
9787 (tok != ',' || sa->type.t))) &&
9788 tok != -1) {
9789 if (tok == '(')
9790 parlevel++;
9791 else if (tok == ')')
9792 parlevel--;
9793 tok_str_add2(&str, tok, &tokc);
9794 next_nomacro();
9795 }
9796 tok_str_add(&str, 0);
9797 sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, (long)str.str);
9798 sa = sa->next;
9799 if (tok == ')') {
9800
9801
9802 if (sa && sa->type.t && gnu_ext)
9803 continue;
9804 else
9805 break;
9806 }
9807 if (tok != ',')
9808 expect(",");
9809 next_nomacro();
9810 }
9811 if (sa) {
9812 error("macro '%s' used with too few args",
9813 get_tok_str(s->v, 0));
9814 }
9815
9816
9817 = macro_arg_subst(nested_list, mstr, args);
9818
9819 = args;
9820 while (sa) {
9821 sa1 = sa->prev;
9822 tok_str_free((int *)sa->c);
9823 sym_free(sa);
9824 sa = sa1;
9825 }
9826 mstr_allocated = 1;
9827 }
9828 sym_push2(nested_list, s->v, 0, 0);
9829 macro_subst(tok_str, nested_list, mstr, can_read_stream);
9830
9831 = *nested_list;
9832 *nested_list = sa1->prev;
9833 sym_free(sa1);
9834 if (mstr_allocated)
9835 tok_str_free(mstr);
9836 }
9837 return 0;
9838 }
9839
9840
9841
9842 static int *macro_twosharps(const int *macro_str)
9843 {
9844 TokenSym *ts;
9845 const int *macro_ptr1, *start_macro_ptr, *ptr, *saved_macro_ptr;
9846 int t;
9847 const char *p1, *p2;
9848 CValue cval;
9849 TokenString macro_str1;
9850 CString cstr;
9851
9852 start_macro_ptr = macro_str;
9853
9854 for(;;) {
9855 macro_ptr1 = macro_str;
9856 TOK_GET(t, macro_str, cval);
9857
9858 if (t == 0)
9859 return NULL;
9860 if (*macro_str == TOK_TWOSHARPS)
9861 break;
9862 }
9863
9864
9865 (&cstr);
9866 tok_str_new(¯o_str1);
9867 tok = t;
9868 tokc = cval;
9869
9870
9871 for(ptr = start_macro_ptr; ptr < macro_ptr1;) {
9872 TOK_GET(t, ptr, cval);
9873 tok_str_add2(¯o_str1, t, &cval);
9874 }
9875 saved_macro_ptr = macro_ptr;
9876
9877 = (int *)macro_str;
9878 for(;;) {
9879 while (*macro_ptr == TOK_TWOSHARPS) {
9880 macro_ptr++;
9881 macro_ptr1 = macro_ptr;
9882 t = *macro_ptr;
9883 if (t) {
9884 TOK_GET(t, macro_ptr, cval);
9885
9886
9887 (&cstr);
9888 p1 = get_tok_str(tok, &tokc);
9889 cstr_cat(&cstr, p1);
9890 p2 = get_tok_str(t, &cval);
9891 cstr_cat(&cstr, p2);
9892 cstr_ccat(&cstr, '\0');
9893
9894 if ((tok >= TOK_IDENT || tok == TOK_PPNUM) &&
9895 (t >= TOK_IDENT || t == TOK_PPNUM)) {
9896 if (tok == TOK_PPNUM) {
9897
9898
9899
9900 .cstr = &cstr;
9901 } else {
9902
9903
9904 if (t == TOK_PPNUM) {
9905 const char *p;
9906 int c;
9907
9908 p = p2;
9909 for(;;) {
9910 c = *p;
9911 if (c == '\0')
9912 break;
9913 p++;
9914 if (!isnum(c) && !isid(c))
9915 goto error_pasting;
9916 }
9917 }
9918 ts = tok_alloc(cstr.data, strlen(cstr.data));
9919 tok = ts->tok;
9920 }
9921 } else {
9922 const char *str = cstr.data;
9923 const unsigned char *q;
9924
9925
9926
9927 if (!strcmp(str, ">>=")) {
9928 tok = TOK_A_SAR;
9929 } else if (!strcmp(str, "<<=")) {
9930 tok = TOK_A_SHL;
9931 } else if (strlen(str) == 2) {
9932
9933 = tok_two_chars;
9934 for(;;) {
9935 if (!*q)
9936 goto error_pasting;
9937 if (q[0] == str[0] && q[1] == str[1])
9938 break;
9939 q += 3;
9940 }
9941 tok = q[2];
9942 } else {
9943 error_pasting:
9944
9945
9946 (&cstr);
9947 p1 = get_tok_str(tok, &tokc);
9948 cstr_cat(&cstr, p1);
9949 cstr_ccat(&cstr, '\0');
9950 p2 = get_tok_str(t, &cval);
9951 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr.data, p2);
9952
9953 (¯o_str1, tok, &tokc);
9954
9955 = t;
9956 tokc = cval;
9957 }
9958 }
9959 }
9960 }
9961 tok_str_add2(¯o_str1, tok, &tokc);
9962 next_nomacro();
9963 if (tok == 0)
9964 break;
9965 }
9966 macro_ptr = (int *)saved_macro_ptr;
9967 cstr_free(&cstr);
9968 tok_str_add(¯o_str1, 0);
9969 return macro_str1.str;
9970 }
9971
9972
9973
9974
9975
9976 static void macro_subst(TokenString *tok_str, Sym **nested_list,
9977 const int *macro_str, struct macro_level ** can_read_stream)
9978 {
9979 Sym *s;
9980 int *macro_str1;
9981 const int *ptr;
9982 int t, ret;
9983 CValue cval;
9984 struct macro_level ml;
9985
9986
9987 = macro_str;
9988 macro_str1 = macro_twosharps(ptr);
9989 if (macro_str1)
9990 ptr = macro_str1;
9991 while (1) {
9992
9993
9994 if (ptr == NULL)
9995 break;
9996 TOK_GET(t, ptr, cval);
9997 if (t == 0)
9998 break;
9999 s = define_find(t);
10000 if (s != NULL) {
10001
10002 if (sym_find2(*nested_list, t))
10003 goto no_subst;
10004 ml.p = macro_ptr;
10005 if (can_read_stream)
10006 ml.prev = *can_read_stream, *can_read_stream = &ml;
10007 macro_ptr = (int *)ptr;
10008 tok = t;
10009 ret = macro_subst_tok(tok_str, nested_list, s, can_read_stream);
10010 ptr = (int *)macro_ptr;
10011 macro_ptr = ml.p;
10012 if (can_read_stream && *can_read_stream == &ml)
10013 *can_read_stream = ml.prev;
10014 if (ret != 0)
10015 goto no_subst;
10016 } else {
10017 no_subst:
10018 tok_str_add2(tok_str, t, &cval);
10019 }
10020 }
10021 if (macro_str1)
10022 tok_str_free(macro_str1);
10023 }
10024
10025
10026 static void next(void)
10027 {
10028 Sym *nested_list, *s;
10029 TokenString str;
10030 struct macro_level *ml;
10031
10032 redo:
10033 next_nomacro();
10034 if (!macro_ptr) {
10035
10036
10037 if (tok >= TOK_IDENT &&
10038 (parse_flags & PARSE_FLAG_PREPROCESS)) {
10039 s = define_find(tok);
10040 if (s) {
10041
10042 (&str);
10043 nested_list = NULL;
10044 ml = NULL;
10045 if (macro_subst_tok(&str, &nested_list, s, &ml) == 0) {
10046
10047 (&str, 0);
10048 macro_ptr = str.str;
10049 macro_ptr_allocated = str.str;
10050 goto redo;
10051 }
10052 }
10053 }
10054 } else {
10055 if (tok == 0) {
10056
10057 if (unget_buffer_enabled) {
10058 macro_ptr = unget_saved_macro_ptr;
10059 unget_buffer_enabled = 0;
10060 } else {
10061
10062 (macro_ptr_allocated);
10063 macro_ptr = NULL;
10064 }
10065 goto redo;
10066 }
10067 }
10068
10069
10070 if (tok == TOK_PPNUM &&
10071 (parse_flags & PARSE_FLAG_TOK_NUM)) {
10072 parse_number((char *)tokc.cstr->data);
10073 }
10074 }
10075
10076
10077
10078 static inline void unget_tok(int last_tok)
10079 {
10080 int i, n;
10081 int *q;
10082 unget_saved_macro_ptr = macro_ptr;
10083 unget_buffer_enabled = 1;
10084 q = unget_saved_buffer;
10085 macro_ptr = q;
10086 *q++ = tok;
10087 n = tok_ext_size(tok) - 1;
10088 for(i=0;i<n;i++)
10089 *q++ = tokc.tab[i];
10090 *q = 0;
10091 = last_tok;
10092 }
10093
10094
10095 void swap(int *p, int *q)
10096 {
10097 int t;
10098 t = *p;
10099 *p = *q;
10100 *q = t;
10101 }
10102
10103 void vsetc(CType *type, int r, CValue *vc)
10104 {
10105 int v;
10106
10107 if (vtop >= vstack + (VSTACK_SIZE - 1))
10108 error("memory full");
10109
10110
10111
10112 if (vtop >= vstack) {
10113 v = vtop->r & VT_VALMASK;
10114 if (v == VT_CMP || (v & ~1) == VT_JMP)
10115 gv(RC_INT);
10116 }
10117 vtop++;
10118 vtop->type = *type;
10119 vtop->r = r;
10120 vtop->r2 = VT_CONST;
10121 vtop->c = *vc;
10122 }
10123
10124
10125 void vpushi(int v)
10126 {
10127 CValue cval;
10128 cval.i = v;
10129 vsetc(&int_type, VT_CONST, &cval);
10130 }
10131
10132
10133 static Sym *get_sym_ref(CType *type, Section *sec,
10134 unsigned long offset, unsigned long size)
10135 {
10136 int v;
10137 Sym *sym;
10138
10139 v = anon_sym++;
10140 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
10141 sym->type.ref = type->ref;
10142 sym->r = VT_CONST | VT_SYM;
10143 put_extern_sym(sym, sec, offset, size);
10144 return sym;
10145 }
10146
10147
10148 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
10149 {
10150 CValue cval;
10151
10152 cval.ul = 0;
10153 vsetc(type, VT_CONST | VT_SYM, &cval);
10154 vtop->sym = get_sym_ref(type, sec, offset, size);
10155 }
10156
10157
10158 static Sym *external_global_sym(int v, CType *type, int r)
10159 {
10160 Sym *s;
10161
10162 s = sym_find(v);
10163 if (!s) {
10164
10165 = global_identifier_push(v, type->t | VT_EXTERN, 0);
10166 s->type.ref = type->ref;
10167 s->r = r | VT_CONST | VT_SYM;
10168 }
10169 return s;
10170 }
10171
10172
10173 static Sym *external_sym(int v, CType *type, int r)
10174 {
10175 Sym *s;
10176
10177 s = sym_find(v);
10178 if (!s) {
10179
10180 = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
10181 s->type.t |= VT_EXTERN;
10182 } else {
10183 if (!is_compatible_types(&s->type, type))
10184 error("incompatible types for redefinition of '%s'",
10185 get_tok_str(v, NULL));
10186 }
10187 return s;
10188 }
10189
10190
10191 static void vpush_global_sym(CType *type, int v)
10192 {
10193 Sym *sym;
10194 CValue cval;
10195
10196 sym = external_global_sym(v, type, 0);
10197 cval.ul = 0;
10198 vsetc(type, VT_CONST | VT_SYM, &cval);
10199 vtop->sym = sym;
10200 }
10201
10202 void vset(CType *type, int r, int v)
10203 {
10204 CValue cval;
10205
10206 cval.i = v;
10207 vsetc(type, r, &cval);
10208 }
10209
10210 void vseti(int r, int v)
10211 {
10212 CType type;
10213 type.t = VT_INT;
10214 vset(&type, r, v);
10215 }
10216
10217 void vswap(void)
10218 {
10219 SValue tmp;
10220
10221 tmp = vtop[0];
10222 vtop[0] = vtop[-1];
10223 vtop[-1] = tmp;
10224 }
10225
10226 void vpushv(SValue *v)
10227 {
10228 if (vtop >= vstack + (VSTACK_SIZE - 1))
10229 error("memory full");
10230 vtop++;
10231 *vtop = *v;
10232 }
10233
10234 void vdup(void)
10235 {
10236 vpushv(vtop);
10237 }
10238
10239
10240 void save_reg(int r)
10241 {
10242 int l, saved, size, align;
10243 SValue *p, sv;
10244 CType *type;
10245
10246
10247 = 0;
10248 l = 0;
10249 for(p=vstack;p<=vtop;p++) {
10250 if ((p->r & VT_VALMASK) == r ||
10251 (p->r2 & VT_VALMASK) == r) {
10252
10253 if (!saved) {
10254
10255 = p->r & VT_VALMASK;
10256
10257 = &p->type;
10258 if ((p->r & VT_LVAL) ||
10259 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
10260 type = &int_type;
10261 size = type_size(type, &align);
10262 loc = (loc - size) & -align;
10263 sv.type.t = type->t;
10264 sv.r = VT_LOCAL | VT_LVAL;
10265 sv.c.ul = loc;
10266 store(r, &sv);
10267 #ifdef TCC_TARGET_I386
10268
10269 if (r == TREG_ST0) {
10270 o(0xd9dd);
10271 }
10272 #endif
10273
10274 if ((type->t & VT_BTYPE) == VT_LLONG) {
10275 sv.c.ul += 4;
10276 store(p->r2, &sv);
10277 }
10278 l = loc;
10279 saved = 1;
10280 }
10281
10282 if (p->r & VT_LVAL) {
10283
10284
10285
10286 ->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
10287 } else {
10288 p->r = lvalue_type(p->type.t) | VT_LOCAL;
10289 }
10290 p->r2 = VT_CONST;
10291 p->c.ul = l;
10292 }
10293 }
10294 }
10295
10296
10297
10298 int get_reg_ex(int rc, int rc2)
10299 {
10300 int r;
10301 SValue *p;
10302
10303 for(r=0;r<NB_REGS;r++) {
10304 if (reg_classes[r] & rc2) {
10305 int n;
10306 n=0;
10307 for(p = vstack; p <= vtop; p++) {
10308 if ((p->r & VT_VALMASK) == r ||
10309 (p->r2 & VT_VALMASK) == r)
10310 n++;
10311 }
10312 if (n <= 1)
10313 return r;
10314 }
10315 }
10316 return get_reg(rc);
10317 }
10318
10319
10320 int get_reg(int rc)
10321 {
10322 int r;
10323 SValue *p;
10324
10325
10326 for(r=0;r<NB_REGS;r++) {
10327 if (reg_classes[r] & rc) {
10328 for(p=vstack;p<=vtop;p++) {
10329 if ((p->r & VT_VALMASK) == r ||
10330 (p->r2 & VT_VALMASK) == r)
10331 goto notfound;
10332 }
10333 return r;
10334 }
10335 notfound: ;
10336 }
10337
10338
10339
10340
10341 for(p=vstack;p<=vtop;p++) {
10342 r = p->r & VT_VALMASK;
10343 if (r < VT_CONST && (reg_classes[r] & rc))
10344 goto save_found;
10345
10346 = p->r2 & VT_VALMASK;
10347 if (r < VT_CONST && (reg_classes[r] & rc)) {
10348 save_found:
10349 save_reg(r);
10350 return r;
10351 }
10352 }
10353
10354 return -1;
10355 }
10356
10357
10358 void save_regs(int n)
10359 {
10360 int r;
10361 SValue *p, *p1;
10362 p1 = vtop - n;
10363 for(p = vstack;p <= p1; p++) {
10364 r = p->r & VT_VALMASK;
10365 if (r < VT_CONST) {
10366 save_reg(r);
10367 }
10368 }
10369 }
10370
10371
10372
10373 void move_reg(int r, int s)
10374 {
10375 SValue sv;
10376
10377 if (r != s) {
10378 save_reg(r);
10379 sv.type.t = VT_INT;
10380 sv.r = s;
10381 sv.c.ul = 0;
10382 load(r, &sv);
10383 }
10384 }
10385
10386
10387 void gaddrof(void)
10388 {
10389 vtop->r &= ~VT_LVAL;
10390
10391 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
10392 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
10393 }
10394
10395 #ifdef CONFIG_TCC_BCHECK
10396
10397 void gbound(void)
10398 {
10399 int lval_type;
10400 CType type1;
10401
10402 vtop->r &= ~VT_MUSTBOUND;
10403
10404 if (vtop->r & VT_LVAL) {
10405
10406 if (!(vtop->r & VT_BOUNDED)) {
10407 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
10408
10409 = vtop->type;
10410 vtop->type.t = VT_INT;
10411 gaddrof();
10412 vpushi(0);
10413 gen_bounded_ptr_add();
10414 vtop->r |= lval_type;
10415 vtop->type = type1;
10416 }
10417
10418 ();
10419 }
10420 }
10421 #endif
10422
10423
10424
10425
10426 int gv(int rc)
10427 {
10428 int r, r2, rc2, bit_pos, bit_size, size, align, i;
10429 unsigned long long ll;
10430
10431
10432 if (vtop->type.t & VT_BITFIELD) {
10433 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
10434 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
10435
10436 ->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
10437
10438 (32 - (bit_pos + bit_size));
10439 gen_op(TOK_SHL);
10440 vpushi(32 - bit_size);
10441
10442 (TOK_SAR);
10443 r = gv(rc);
10444 } else {
10445 if (is_float(vtop->type.t) &&
10446 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
10447 Sym *sym;
10448 int *ptr;
10449 unsigned long offset;
10450
10451
10452
10453
10454 = type_size(&vtop->type, &align);
10455 offset = (data_section->data_offset + align - 1) & -align;
10456 data_section->data_offset = offset;
10457
10458 = section_ptr_add(data_section, size);
10459 size = size >> 2;
10460 for(i=0;i<size;i++)
10461 ptr[i] = vtop->c.tab[i];
10462 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
10463 vtop->r |= VT_LVAL | VT_SYM;
10464 vtop->sym = sym;
10465 vtop->c.ul = 0;
10466 }
10467 #ifdef CONFIG_TCC_BCHECK
10468 if (vtop->r & VT_MUSTBOUND)
10469 gbound();
10470 #endif
10471
10472 r = vtop->r & VT_VALMASK;
10473
10474
10475
10476
10477 if (r >= VT_CONST ||
10478 (vtop->r & VT_LVAL) ||
10479 !(reg_classes[r] & rc) ||
10480 ((vtop->type.t & VT_BTYPE) == VT_LLONG &&
10481 !(reg_classes[vtop->r2] & rc))) {
10482 r = get_reg(rc);
10483 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
10484
10485
10486 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
10487
10488 = vtop->c.ull;
10489 vtop->c.ui = ll;
10490 (r, vtop);
10491 vtop->r = r;
10492 (ll >> 32);
10493 } else if (r >= VT_CONST ||
10494 (vtop->r & VT_LVAL)) {
10495
10496
10497
10498
10499 (1);
10500
10501 (r, vtop);
10502 vdup();
10503 vtop[-1].r = r;
10504
10505 ->type.t = VT_INT;
10506 gaddrof();
10507 vpushi(4);
10508 gen_op('+');
10509 vtop->r |= VT_LVAL;
10510 } else {
10511
10512 (r, vtop);
10513 vdup();
10514 vtop[-1].r = r;
10515 ->r = vtop[-1].r2;
10516 }
10517
10518 = RC_INT;
10519 if (rc == RC_IRET)
10520 rc2 = RC_LRET;
10521 r2 = get_reg(rc2);
10522 load(r2, vtop);
10523 vpop();
10524
10525 ->r2 = r2;
10526 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
10527 int t1, t;
10528
10529
10530 = vtop->type.t;
10531 t1 = t;
10532
10533 if (vtop->r & VT_LVAL_BYTE)
10534 t = VT_BYTE;
10535 else if (vtop->r & VT_LVAL_SHORT)
10536 t = VT_SHORT;
10537 if (vtop->r & VT_LVAL_UNSIGNED)
10538 t |= VT_UNSIGNED;
10539 vtop->type.t = t;
10540 load(r, vtop);
10541
10542 ->type.t = t1;
10543 } else {
10544
10545 (r, vtop);
10546 }
10547 }
10548 vtop->r = r;
10549 #ifdef TCC_TARGET_C67
10550
10551 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
10552 vtop->r2 = r+1;
10553 #endif
10554 }
10555 return r;
10556 }
10557
10558
10559 void gv2(int rc1, int rc2)
10560 {
10561 int v;
10562
10563
10564
10565
10566 = vtop[0].r & VT_VALMASK;
10567 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
10568 vswap();
10569 gv(rc1);
10570 vswap();
10571 gv(rc2);
10572
10573 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
10574 vswap();
10575 gv(rc1);
10576 vswap();
10577 }
10578 } else {
10579 gv(rc2);
10580 vswap();
10581 gv(rc1);
10582 vswap();
10583
10584 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
10585 gv(rc2);
10586 }
10587 }
10588 }
10589
10590
10591 void lexpand(void)
10592 {
10593 int u;
10594
10595 u = vtop->type.t & VT_UNSIGNED;
10596 gv(RC_INT);
10597 vdup();
10598 vtop[0].r = vtop[-1].r2;
10599 vtop[0].r2 = VT_CONST;
10600 vtop[-1].r2 = VT_CONST;
10601 vtop[0].type.t = VT_INT | u;
10602 vtop[-1].type.t = VT_INT | u;
10603 }
10604
10605 #ifdef TCC_TARGET_ARM
10606
10607 void lexpand_nr(void)
10608 {
10609 int u,v;
10610
10611 u = vtop->type.t & VT_UNSIGNED;
10612 vdup();
10613 vtop->r2 = VT_CONST;
10614 vtop->type.t = VT_INT | u;
10615 v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
10616 if (v == VT_CONST) {
10617 vtop[-1].c.ui = vtop->c.ull;
10618 vtop->c.ui = vtop->c.ull >> 32;
10619 vtop->r = VT_CONST;
10620 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
10621 vtop->c.ui += 4;
10622 vtop->r = vtop[-1].r;
10623 } else if (v > VT_CONST) {
10624 vtop--;
10625 lexpand();
10626 } else
10627 vtop->r = vtop[-1].r2;
10628 vtop[-1].r2 = VT_CONST;
10629 vtop[-1].type.t = VT_INT | u;
10630 }
10631 #endif
10632
10633
10634 void lbuild(int t)
10635 {
10636 gv2(RC_INT, RC_INT);
10637 vtop[-1].r2 = vtop[0].r;
10638 vtop[-1].type.t = t;
10639 vpop();
10640 }
10641
10642
10643
10644
10645 void vrotb(int n)
10646 {
10647 int i;
10648 SValue tmp;
10649
10650 tmp = vtop[-n + 1];
10651 for(i=-n+1;i!=0;i++)
10652 vtop[i] = vtop[i+1];
10653 vtop[0] = tmp;
10654 }
10655
10656
10657
10658
10659 void vrott(int n)
10660 {
10661 int i;
10662 SValue tmp;
10663
10664 tmp = vtop[0];
10665 for(i = 0;i < n - 1; i++)
10666 vtop[-i] = vtop[-i - 1];
10667 vtop[-n + 1] = tmp;
10668 }
10669
10670 #ifdef TCC_TARGET_ARM
10671
10672
10673
10674 void vnrott(int n)
10675 {
10676 int i;
10677 SValue tmp;
10678
10679 tmp = vtop[-n + 1];
10680 for(i = n - 1; i > 0; i--)
10681 vtop[-i] = vtop[-i + 1];
10682 vtop[0] = tmp;
10683 }
10684 #endif
10685
10686
10687 void vpop(void)
10688 {
10689 int v;
10690 v = vtop->r & VT_VALMASK;
10691 #ifdef TCC_TARGET_I386
10692
10693 if (v == TREG_ST0 && !nocode_wanted) {
10694 o(0xd9dd);
10695 } else
10696 #endif
10697 if (v == VT_JMP || v == VT_JMPI) {
10698
10699 (vtop->c.ul);
10700 }
10701 vtop--;
10702 }
10703
10704
10705
10706 void gv_dup(void)
10707 {
10708 int rc, t, r, r1;
10709 SValue sv;
10710
10711 t = vtop->type.t;
10712 if ((t & VT_BTYPE) == VT_LLONG) {
10713 lexpand();
10714 gv_dup();
10715 vswap();
10716 vrotb(3);
10717 gv_dup();
10718 vrotb(4);
10719
10720 (t);
10721 vrotb(3);
10722 vrotb(3);
10723 vswap();
10724 lbuild(t);
10725 vswap();
10726 } else {
10727
10728 = RC_INT;
10729 sv.type.t = VT_INT;
10730 if (is_float(t)) {
10731 rc = RC_FLOAT;
10732 sv.type.t = t;
10733 }
10734 r = gv(rc);
10735 r1 = get_reg(rc);
10736 sv.r = r;
10737 sv.c.ul = 0;
10738 load(r1, &sv);
10739 ();
10740
10741 ->r = r1;
10742 }
10743 }
10744
10745
10746 void gen_opl(int op)
10747 {
10748 int t, a, b, op1, c, i;
10749 int func;
10750 SValue tmp;
10751
10752 switch(op) {
10753 case '/':
10754 case TOK_PDIV:
10755 func = TOK___divdi3;
10756 goto gen_func;
10757 case TOK_UDIV:
10758 func = TOK___udivdi3;
10759 goto gen_func;
10760 case '%':
10761 func = TOK___moddi3;
10762 goto gen_func;
10763 case TOK_UMOD:
10764 func = TOK___umoddi3;
10765 gen_func:
10766
10767 (&func_old_type, func);
10768 vrott(3);
10769 gfunc_call(2);
10770 vpushi(0);
10771 vtop->r = REG_IRET;
10772 vtop->r2 = REG_LRET;
10773 break;
10774 case '^':
10775 case '&':
10776 case '|':
10777 case '*':
10778 case '+':
10779 case '-':
10780 t = vtop->type.t;
10781 vswap();
10782 lexpand();
10783 vrotb(3);
10784 lexpand();
10785
10786 = vtop[0];
10787 vtop[0] = vtop[-3];
10788 vtop[-3] = tmp;
10789 tmp = vtop[-2];
10790 vtop[-2] = vtop[-3];
10791 vtop[-3] = tmp;
10792 vswap();
10793
10794 if (op == '*') {
10795 vpushv(vtop - 1);
10796 vpushv(vtop - 1);
10797 gen_op(TOK_UMULL);
10798 lexpand();
10799
10800 for(i=0;i<4;i++)
10801 vrotb(6);
10802
10803 = vtop[0];
10804 vtop[0] = vtop[-2];
10805 vtop[-2] = tmp;
10806
10807 ('*');
10808 vrotb(3);
10809 vrotb(3);
10810 gen_op('*');
10811
10812 ('+');
10813 gen_op('+');
10814 } else if (op == '+' || op == '-') {
10815
10816 if (op == '+')
10817 op1 = TOK_ADDC1;
10818 else
10819 op1 = TOK_SUBC1;
10820 gen_op(op1);
10821
10822 (3);
10823 vrotb(3);
10824 gen_op(op1 + 1);
10825 } else {
10826 gen_op(op);
10827
10828 (3);
10829 vrotb(3);
10830
10831 (op);
10832
10833 }
10834
10835 (t);
10836 break;
10837 case TOK_SAR:
10838 case TOK_SHR:
10839 case TOK_SHL:
10840 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
10841 t = vtop[-1].type.t;
10842 vswap();
10843 lexpand();
10844 vrotb(3);
10845
10846 = (int)vtop->c.i;
10847
10848
10849
10850 ();
10851 if (op != TOK_SHL)
10852 vswap();
10853 if (c >= 32) {
10854
10855 ();
10856 if (c > 32) {
10857 vpushi(c - 32);
10858 gen_op(op);
10859 }
10860 if (op != TOK_SAR) {
10861 vpushi(0);
10862 } else {
10863 gv_dup();
10864 vpushi(31);
10865 gen_op(TOK_SAR);
10866 }
10867 vswap();
10868 } else {
10869 vswap();
10870 gv_dup();
10871
10872 (c);
10873 gen_op(op);
10874 vswap();
10875 vpushi(32 - c);
10876 if (op == TOK_SHL)
10877 gen_op(TOK_SHR);
10878 else
10879 gen_op(TOK_SHL);
10880 vrotb(3);
10881
10882 (c);
10883 if (op == TOK_SHL)
10884 gen_op(TOK_SHL);
10885 else
10886 gen_op(TOK_SHR);
10887 gen_op('|');
10888 }
10889 if (op != TOK_SHL)
10890 vswap();
10891 lbuild(t);
10892 } else {
10893
10894 switch(op) {
10895 case TOK_SAR:
10896 func = TOK___sardi3;
10897 goto gen_func;
10898 case TOK_SHR:
10899 func = TOK___shrdi3;
10900 goto gen_func;
10901 case TOK_SHL:
10902 func = TOK___shldi3;
10903 goto gen_func;
10904 }
10905 }
10906 break;
10907 default:
10908
10909 = vtop->type.t;
10910 vswap();
10911 lexpand();
10912 vrotb(3);
10913 lexpand();
10914
10915 = vtop[-1];
10916 vtop[-1] = vtop[-2];
10917 vtop[-2] = tmp;
10918
10919
10920 = op;
10921
10922
10923 if (op1 == TOK_LT)
10924 op1 = TOK_LE;
10925 else if (op1 == TOK_GT)
10926 op1 = TOK_GE;
10927 else if (op1 == TOK_ULT)
10928 op1 = TOK_ULE;
10929 else if (op1 == TOK_UGT)
10930 op1 = TOK_UGE;
10931 a = 0;
10932 b = 0;
10933 gen_op(op1);
10934 if (op1 != TOK_NE) {
10935 a = gtst(1, 0);
10936 }
10937 if (op != TOK_EQ) {
10938
10939
10940 if (a == 0) {
10941 b = gtst(0, 0);
10942 } else {
10943 #if defined(TCC_TARGET_I386)
10944 b = psym(0x850f, 0);
10945 #elif defined(TCC_TARGET_ARM)
10946 b = ind;
10947 o(0x1A000000 | encbranch(ind, 0, 1));
10948 #elif defined(TCC_TARGET_C67)
10949 error("not implemented");
10950 #else
10951 #error not supported
10952 #endif
10953 }
10954 }
10955
10956 = op;
10957 if (op1 == TOK_LT)
10958 op1 = TOK_ULT;
10959 else if (op1 == TOK_LE)
10960 op1 = TOK_ULE;
10961 else if (op1 == TOK_GT)
10962 op1 = TOK_UGT;
10963 else if (op1 == TOK_GE)
10964 op1 = TOK_UGE;
10965 gen_op(op1);
10966 a = gtst(1, a);
10967 gsym(b);
10968 vseti(VT_JMPI, a);
10969 break;
10970 }
10971 }
10972
10973
10974
10975 void gen_opic(int op)
10976 {
10977 int fc, c1, c2, n;
10978 SValue *v1, *v2;
10979
10980 v1 = vtop - 1;
10981 v2 = vtop;
10982
10983 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
10984 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
10985 if (c1 && c2) {
10986 fc = v2->c.i;
10987 switch(op) {
10988 case '+': v1->c.i += fc; break;
10989 case '-': v1->c.i -= fc; break;
10990 case '&': v1->c.i &= fc; break;
10991 case '^': v1->c.i ^= fc; break;
10992 case '|': v1->c.i |= fc; break;
10993 case '*': v1->c.i *= fc; break;
10994
10995 case TOK_PDIV:
10996 case '/':
10997 case '%':
10998 case TOK_UDIV:
10999 case TOK_UMOD:
11000
11001 if (fc == 0) {
11002 if (const_wanted)
11003 error("division by zero in constant");
11004 goto general_case;
11005 }
11006 switch(op) {
11007 default: v1->c.i /= fc; break;
11008 case '%': v1->c.i %= fc; break;
11009 case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break;
11010 case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break;
11011 }
11012 break;
11013 case TOK_SHL: v1->c.i <<= fc; break;
11014 case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
11015 case TOK_SAR: v1->c.i >>= fc; break;
11016
11017 case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
11018 case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
11019 case TOK_EQ: v1->c.i = v1->c.i == fc; break;
11020 case TOK_NE: v1->c.i = v1->c.i != fc; break;
11021 case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
11022 case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
11023 case TOK_LT: v1->c.i = v1->c.i < fc; break;
11024 case TOK_GE: v1->c.i = v1->c.i >= fc; break;
11025 case TOK_LE: v1->c.i = v1->c.i <= fc; break;
11026 case TOK_GT: v1->c.i = v1->c.i > fc; break;
11027
11028 case TOK_LAND: v1->c.i = v1->c.i && fc; break;
11029 case TOK_LOR: v1->c.i = v1->c.i || fc; break;
11030 default:
11031 goto general_case;
11032 }
11033 vtop--;
11034 } else {
11035
11036 if (c1 && (op == '+' || op == '&' || op == '^' ||
11037 op == '|' || op == '*')) {
11038 vswap();
11039 swap(&c1, &c2);
11040 }
11041 fc = vtop->c.i;
11042 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
11043 op == TOK_PDIV) &&
11044 fc == 1) ||
11045 ((op == '+' || op == '-' || op == '|' || op == '^' ||
11046 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
11047 fc == 0) ||
11048 (op == '&' &&
11049 fc == -1))) {
11050
11051 --;
11052 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
11053
11054 if (fc > 0 && (fc & (fc - 1)) == 0) {
11055 n = -1;
11056 while (fc) {
11057 fc >>= 1;
11058 n++;
11059 }
11060 vtop->c.i = n;
11061 if (op == '*')
11062 op = TOK_SHL;
11063 else if (op == TOK_PDIV)
11064 op = TOK_SAR;
11065 else
11066 op = TOK_SHR;
11067 }
11068 goto general_case;
11069 } else if (c2 && (op == '+' || op == '-') &&
11070 (vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) ==
11071 (VT_CONST | VT_SYM)) {
11072
11073 if (op == '-')
11074 fc = -fc;
11075 vtop--;
11076 vtop->c.i += fc;
11077 } else {
11078 general_case:
11079 if (!nocode_wanted) {
11080
11081 (op);
11082 } else {
11083 vtop--;
11084 }
11085 }
11086 }
11087 }
11088
11089
11090 void gen_opif(int op)
11091 {
11092 int c1, c2;
11093 SValue *v1, *v2;
11094 long double f1, f2;
11095
11096 v1 = vtop - 1;
11097 v2 = vtop;
11098
11099 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
11100 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
11101 if (c1 && c2) {
11102 if (v1->type.t == VT_FLOAT) {
11103 f1 = v1->c.f;
11104 f2 = v2->c.f;
11105 } else if (v1->type.t == VT_DOUBLE) {
11106 f1 = v1->c.d;
11107 f2 = v2->c.d;
11108 } else {
11109 f1 = v1->c.ld;
11110 f2 = v2->c.ld;
11111 }
11112
11113
11114
11115 if (!ieee_finite(f1) || !ieee_finite(f2))
11116 goto general_case;
11117
11118 switch(op) {
11119 case '+': f1 += f2; break;
11120 case '-': f1 -= f2; break;
11121 case '*': f1 *= f2; break;
11122 case '/':
11123 if (f2 == 0.0) {
11124 if (const_wanted)
11125 error("division by zero in constant");
11126 goto general_case;
11127 }
11128 f1 /= f2;
11129 break;
11130
11131 default:
11132 goto general_case;
11133 }
11134
11135 if (v1->type.t == VT_FLOAT) {
11136 v1->c.f = f1;
11137 } else if (v1->type.t == VT_DOUBLE) {
11138 v1->c.d = f1;
11139 } else {
11140 v1->c.ld = f1;
11141 }
11142 vtop--;
11143 } else {
11144 general_case:
11145 if (!nocode_wanted) {
11146 gen_opf(op);
11147 } else {
11148 vtop--;
11149 }
11150 }
11151 }
11152
11153
11154 static inline CType *pointed_type(CType *type)
11155 {
11156 return &type->ref->type;
11157 }
11158
11159 static int pointed_size(CType *type)
11160 {
11161 int align;
11162 return type_size(pointed_type(type), &align);
11163 }
11164
11165 static inline int is_null_pointer(SValue *p)
11166 {
11167 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
11168 return 0;
11169 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
11170 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0);
11171 }
11172
11173 static inline int is_integer_btype(int bt)
11174 {
11175 return (bt == VT_BYTE || bt == VT_SHORT ||
11176 bt == VT_INT || bt == VT_LLONG);
11177 }
11178
11179
11180 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
11181 {
11182 CType *type1, *type2, tmp_type1, tmp_type2;
11183 int bt1, bt2;
11184
11185
11186 if (is_null_pointer(p1) || is_null_pointer(p2))
11187 return;
11188 type1 = &p1->type;
11189 type2 = &p2->type;
11190 bt1 = type1->t & VT_BTYPE;
11191 bt2 = type2->t & VT_BTYPE;
11192
11193 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
11194 warning("comparison between pointer and integer");
11195 return;
11196 }
11197
11198
11199 if (bt1 == VT_PTR) {
11200 type1 = pointed_type(type1);
11201 } else if (bt1 != VT_FUNC)
11202 goto invalid_operands;
11203
11204 if (bt2 == VT_PTR) {
11205 type2 = pointed_type(type2);
11206 } else if (bt2 != VT_FUNC) {
11207 invalid_operands:
11208 error("invalid operands to binary %s", get_tok_str(op, NULL));
11209 }
11210 if ((type1->t & VT_BTYPE) == VT_VOID ||
11211 (type2->t & VT_BTYPE) == VT_VOID)
11212 return;
11213 tmp_type1 = *type1;
11214 tmp_type2 = *type2;
11215 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
11216 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
11217 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
11218
11219 if (op == '-')
11220 goto invalid_operands;
11221 else
11222 warning("comparison of distinct pointer types lacks a cast");
11223 }
11224 }
11225
11226
11227 void gen_op(int op)
11228 {
11229 int u, t1, t2, bt1, bt2, t;
11230 CType type1;
11231
11232 t1 = vtop[-1].type.t;
11233 t2 = vtop[0].type.t;
11234 bt1 = t1 & VT_BTYPE;
11235 bt2 = t2 & VT_BTYPE;
11236
11237 if (bt1 == VT_PTR || bt2 == VT_PTR) {
11238
11239
11240 if (op >= TOK_ULT && op <= TOK_GT) {
11241 check_comparison_pointer_types(vtop - 1, vtop, op);
11242
11243 = VT_INT | VT_UNSIGNED;
11244 goto std_op;
11245 }
11246
11247 if (bt1 == VT_PTR && bt2 == VT_PTR) {
11248 if (op != '-')
11249 error("cannot use pointers here");
11250 check_comparison_pointer_types(vtop - 1, vtop, op);
11251
11252 = pointed_size(&vtop[-1].type);
11253 gen_opic(op);
11254
11255 ->type.t = VT_INT;
11256 vpushi(u);
11257 gen_op(TOK_PDIV);
11258 } else {
11259
11260 if (op != '-' && op != '+')
11261 error("cannot use pointers here");
11262
11263 if (bt2 == VT_PTR) {
11264 vswap();
11265 swap(&t1, &t2);
11266 }
11267 type1 = vtop[-1].type;
11268
11269 (pointed_size(&vtop[-1].type));
11270 gen_op('*');
11271 #ifdef CONFIG_TCC_BCHECK
11272
11273
11274 if (do_bounds_check && !const_wanted) {
11275
11276
11277 if (op == '-') {
11278 vpushi(0);
11279 vswap();
11280 gen_op('-');
11281 }
11282 gen_bounded_ptr_add();
11283 } else
11284 #endif
11285 {
11286 gen_opic(op);
11287 }
11288
11289 ->type = type1;
11290 }
11291 } else if (is_float(bt1) || is_float(bt2)) {
11292
11293 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
11294 t = VT_LDOUBLE;
11295 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
11296 t = VT_DOUBLE;
11297 } else {
11298 t = VT_FLOAT;
11299 }
11300
11301 if (op != '+' && op != '-' && op != '*' && op != '/' &&
11302 (op < TOK_ULT || op > TOK_GT))
11303 error("invalid operands for binary operation");
11304 goto std_op;
11305 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
11306
11307 = VT_LLONG;
11308
11309 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
11310 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
11311 t |= VT_UNSIGNED;
11312 goto std_op;
11313 } else {
11314
11315 = VT_INT;
11316
11317 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
11318 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
11319 t |= VT_UNSIGNED;
11320 std_op:
11321
11322
11323 if (t & VT_UNSIGNED) {
11324 if (op == TOK_SAR)
11325 op = TOK_SHR;
11326 else if (op == '/')
11327 op = TOK_UDIV;
11328 else if (op == '%')
11329 op = TOK_UMOD;
11330 else if (op == TOK_LT)
11331 op = TOK_ULT;
11332 else if (op == TOK_GT)
11333 op = TOK_UGT;
11334 else if (op == TOK_LE)
11335 op = TOK_ULE;
11336 else if (op == TOK_GE)
11337 op = TOK_UGE;
11338 }
11339 vswap();
11340 type1.t = t;
11341 gen_cast(&type1);
11342 vswap();
11343
11344
11345 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
11346 type1.t = VT_INT;
11347 gen_cast(&type1);
11348 if (is_float(t))
11349 gen_opif(op);
11350 else if ((t & VT_BTYPE) == VT_LLONG)
11351 gen_opl(op);
11352 else
11353 gen_opic(op);
11354 if (op >= TOK_ULT && op <= TOK_GT) {
11355
11356 ->type.t = VT_INT;
11357 } else {
11358 vtop->type.t = t;
11359 }
11360 }
11361 }
11362
11363
11364 void gen_cvt_itof1(int t)
11365 {
11366 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
11367 (VT_LLONG | VT_UNSIGNED)) {
11368
11369 if (t == VT_FLOAT)
11370 vpush_global_sym(&func_old_type, TOK___ulltof);
11371 else if (t == VT_DOUBLE)
11372 vpush_global_sym(&func_old_type, TOK___ulltod);
11373 else
11374 vpush_global_sym(&func_old_type, TOK___ulltold);
11375 vrott(2);
11376 gfunc_call(1);
11377 vpushi(0);
11378 vtop->r = REG_FRET;
11379 } else {
11380 gen_cvt_itof(t);
11381 }
11382 }
11383
11384
11385 void gen_cvt_ftoi1(int t)
11386 {
11387 int st;
11388
11389 if (t == (VT_LLONG | VT_UNSIGNED)) {
11390
11391 = vtop->type.t & VT_BTYPE;
11392 if (st == VT_FLOAT)
11393 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
11394 else if (st == VT_DOUBLE)
11395 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
11396 else
11397 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
11398 vrott(2);
11399 gfunc_call(1);
11400 vpushi(0);
11401 vtop->r = REG_IRET;
11402 vtop->r2 = REG_LRET;
11403 } else {
11404 gen_cvt_ftoi(t);
11405 }
11406 }
11407
11408
11409 void force_charshort_cast(int t)
11410 {
11411 int bits, dbt;
11412 dbt = t & VT_BTYPE;
11413
11414 if (dbt == VT_BYTE)
11415 bits = 8;
11416 else
11417 bits = 16;
11418 if (t & VT_UNSIGNED) {
11419 vpushi((1 << bits) - 1);
11420 gen_op('&');
11421 } else {
11422 bits = 32 - bits;
11423 vpushi(bits);
11424 gen_op(TOK_SHL);
11425 vpushi(bits);
11426 gen_op(TOK_SAR);
11427 }
11428 }
11429
11430
11431 static void gen_cast(CType *type)
11432 {
11433 int sbt, dbt, sf, df, c;
11434
11435
11436
11437
11438 if (vtop->r & VT_MUSTCAST) {
11439 vtop->r &= ~VT_MUSTCAST;
11440 force_charshort_cast(vtop->type.t);
11441 }
11442
11443
11444 if (vtop->type.t & VT_BITFIELD) {
11445 gv(RC_INT);
11446 }
11447
11448 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
11449 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
11450
11451 if (sbt != dbt && !nocode_wanted) {
11452 sf = is_float(sbt);
11453 df = is_float(dbt);
11454 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
11455 if (sf && df) {
11456
11457 if (c) {
11458
11459
11460 if (dbt == VT_FLOAT && sbt == VT_DOUBLE)
11461 vtop->c.f = (float)vtop->c.d;
11462 else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE)
11463 vtop->c.f = (float)vtop->c.ld;
11464 else if (dbt == VT_DOUBLE && sbt == VT_FLOAT)
11465 vtop->c.d = (double)vtop->c.f;
11466 else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE)
11467 vtop->c.d = (double)vtop->c.ld;
11468 else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT)
11469 vtop->c.ld = (long double)vtop->c.f;
11470 else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE)
11471 vtop->c.ld = (long double)vtop->c.d;
11472 } else {
11473
11474 (dbt);
11475 }
11476 } else if (df) {
11477
11478 if (c) {
11479 switch(sbt) {
11480 case VT_LLONG | VT_UNSIGNED:
11481 case VT_LLONG:
11482
11483 goto do_itof;
11484 case VT_INT | VT_UNSIGNED:
11485 switch(dbt) {
11486 case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
11487 case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
11488 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
11489 }
11490 break;
11491 default:
11492 switch(dbt) {
11493 case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
11494 case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
11495 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
11496 }
11497 break;
11498 }
11499 } else {
11500 do_itof:
11501 #if !defined(TCC_TARGET_ARM)
11502 gen_cvt_itof1(dbt);
11503 #else
11504 gen_cvt_itof(dbt);
11505 #endif
11506 }
11507 } else if (sf) {
11508
11509
11510 if (dbt != (VT_INT | VT_UNSIGNED) &&
11511 dbt != (VT_LLONG | VT_UNSIGNED) &&
11512 dbt != VT_LLONG)
11513 dbt = VT_INT;
11514 if (c) {
11515 switch(dbt) {
11516 case VT_LLONG | VT_UNSIGNED:
11517 case VT_LLONG:
11518
11519 goto do_ftoi;
11520 case VT_INT | VT_UNSIGNED:
11521 switch(sbt) {
11522 case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
11523 case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
11524 case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
11525 }
11526 break;
11527 default:
11528
11529 switch(sbt) {
11530 case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
11531 case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
11532 case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
11533 }
11534 break;
11535 }
11536 } else {
11537 do_ftoi:
11538 gen_cvt_ftoi1(dbt);
11539 }
11540 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
11541
11542 ->type.t = dbt;
11543 gen_cast(type);
11544 }
11545 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
11546 if ((sbt & VT_BTYPE) != VT_LLONG) {
11547
11548 if (c) {
11549 if (sbt == (VT_INT | VT_UNSIGNED))
11550 vtop->c.ll = vtop->c.ui;
11551 else
11552 vtop->c.ll = vtop->c.i;
11553 } else {
11554
11555 (RC_INT);
11556
11557 if (sbt == (VT_INT | VT_UNSIGNED)) {
11558 vpushi(0);
11559 gv(RC_INT);
11560 } else {
11561 gv_dup();
11562 vpushi(31);
11563 gen_op(TOK_SAR);
11564 }
11565
11566 [-1].r2 = vtop->r;
11567 vpop();
11568 }
11569 }
11570 } else if (dbt == VT_BOOL) {
11571
11572 (0);
11573 gen_op(TOK_NE);
11574 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
11575 (dbt & VT_BTYPE) == VT_SHORT) {
11576 force_charshort_cast(dbt);
11577 } else if ((dbt & VT_BTYPE) == VT_INT) {
11578
11579 if (sbt == VT_LLONG) {
11580
11581 ();
11582 vpop();
11583 }
11584
11585
11586
11587 }
11588 }
11589 vtop->type = *type;
11590 }
11591
11592
11593 static int type_size(CType *type, int *a)
11594 {
11595 Sym *s;
11596 int bt;
11597
11598 bt = type->t & VT_BTYPE;
11599 if (bt == VT_STRUCT) {
11600
11601 = type->ref;
11602 *a = s->r;
11603 return s->c;
11604 } else if (bt == VT_PTR) {
11605 if (type->t & VT_ARRAY) {
11606 s = type->ref;
11607 return type_size(&s->type, a) * s->c;
11608 } else {
11609 *a = PTR_SIZE;
11610 return PTR_SIZE;
11611 }
11612 } else if (bt == VT_LDOUBLE) {
11613 *a = LDOUBLE_ALIGN;
11614 return LDOUBLE_SIZE;
11615 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
11616 #ifdef TCC_TARGET_I386
11617 *a = 4;
11618 #else
11619 *a = 8;
11620 #endif
11621 return 8;
11622 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
11623 *a = 4;
11624 return 4;
11625 } else if (bt == VT_SHORT) {
11626 *a = 2;
11627 return 2;
11628 } else {
11629
11630 *a = 1;
11631 return 1;
11632 }
11633 }
11634
11635
11636 static void mk_pointer(CType *type)
11637 {
11638 Sym *s;
11639 s = sym_push(SYM_FIELD, type, 0, -1);
11640 type->t = VT_PTR | (type->t & ~VT_TYPE);
11641 type->ref = s;
11642 }
11643
11644
11645 static int is_compatible_func(CType *type1, CType *type2)
11646 {
11647 Sym *s1, *s2;
11648
11649 s1 = type1->ref;
11650 s2 = type2->ref;
11651 if (!is_compatible_types(&s1->type, &s2->type))
11652 return 0;
11653
11654 if (s1->r != s2->r)
11655 return 0;
11656
11657 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
11658 return 1;
11659 if (s1->c != s2->c)
11660 return 0;
11661 while (s1 != NULL) {
11662 if (s2 == NULL)
11663 return 0;
11664 if (!is_compatible_types(&s1->type, &s2->type))
11665 return 0;
11666 s1 = s1->next;
11667 s2 = s2->next;
11668 }
11669 if (s2)
11670 return 0;
11671 return 1;
11672 }
11673
11674
11675
11676
11677
11678
11679 static int is_compatible_types(CType *type1, CType *type2)
11680 {
11681 int bt1, t1, t2;
11682
11683 t1 = type1->t & VT_TYPE;
11684 t2 = type2->t & VT_TYPE;
11685
11686 if (t1 != t2)
11687 return 0;
11688
11689 = t1 & VT_BTYPE;
11690 if (bt1 == VT_PTR) {
11691 type1 = pointed_type(type1);
11692 type2 = pointed_type(type2);
11693 return is_compatible_types(type1, type2);
11694 } else if (bt1 == VT_STRUCT) {
11695 return (type1->ref == type2->ref);
11696 } else if (bt1 == VT_FUNC) {
11697 return is_compatible_func(type1, type2);
11698 } else {
11699 return 1;
11700 }
11701 }
11702
11703
11704
11705
11706
11707 void type_to_str(char *buf, int buf_size,
11708 CType *type, const char *varstr)
11709 {
11710 int bt, v, t;
11711 Sym *s, *sa;
11712 char buf1[256];
11713 const char *tstr;
11714
11715 t = type->t & VT_TYPE;
11716 bt = t & VT_BTYPE;
11717 buf[0] = '\0';
11718 if (t & VT_CONSTANT)
11719 pstrcat(buf, buf_size, "const ");
11720 if (t & VT_VOLATILE)
11721 pstrcat(buf, buf_size, "volatile ");
11722 if (t & VT_UNSIGNED)
11723 pstrcat(buf, buf_size, "unsigned ");
11724 switch(bt) {
11725 case VT_VOID:
11726 tstr = "void";
11727 goto add_tstr;
11728 case VT_BOOL:
11729 tstr = "_Bool";
11730 goto add_tstr;
11731 case VT_BYTE:
11732 tstr = "char";
11733 goto add_tstr;
11734 case VT_SHORT:
11735 tstr = "short";
11736 goto add_tstr;
11737 case VT_INT:
11738 tstr = "int";
11739 goto add_tstr;
11740 case VT_LONG:
11741 tstr = "long";
11742 goto add_tstr;
11743 case VT_LLONG:
11744 tstr = "long long";
11745 goto add_tstr;
11746 case VT_FLOAT:
11747 tstr = "float";
11748 goto add_tstr;
11749 case VT_DOUBLE:
11750 tstr = "double";
11751 goto add_tstr;
11752 case VT_LDOUBLE:
11753 tstr = "long double";
11754 add_tstr:
11755 pstrcat(buf, buf_size, tstr);
11756 break;
11757 case VT_ENUM:
11758 case VT_STRUCT:
11759 if (bt == VT_STRUCT)
11760 tstr = "struct ";
11761 else
11762 tstr = "enum ";
11763 pstrcat(buf, buf_size, tstr);
11764 v = type->ref->v & ~SYM_STRUCT;
11765 if (v >= SYM_FIRST_ANOM)
11766 pstrcat(buf, buf_size, "<anonymous>");
11767 else
11768 pstrcat(buf, buf_size, get_tok_str(v, NULL));
11769 break;
11770 case VT_FUNC:
11771 s = type->ref;
11772 type_to_str(buf, buf_size, &s->type, varstr);
11773 pstrcat(buf, buf_size, "(");
11774 sa = s->next;
11775 while (sa != NULL) {
11776 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
11777 pstrcat(buf, buf_size, buf1);
11778 sa = sa->next;
11779 if (sa)
11780 pstrcat(buf, buf_size, ", ");
11781 }
11782 pstrcat(buf, buf_size, ")");
11783 goto no_var;
11784 case VT_PTR:
11785 s = type->ref;
11786 pstrcpy(buf1, sizeof(buf1), "*");
11787 if (varstr)
11788 pstrcat(buf1, sizeof(buf1), varstr);
11789 type_to_str(buf, buf_size, &s->type, buf1);
11790 goto no_var;
11791 }
11792 if (varstr) {
11793 pstrcat(buf, buf_size, " ");
11794 pstrcat(buf, buf_size, varstr);
11795 }
11796 no_var: ;
11797 }
11798
11799
11800
11801 static void gen_assign_cast(CType *dt)
11802 {
11803 CType *st, *type1, *type2, tmp_type1, tmp_type2;
11804 char buf1[256], buf2[256];
11805 int dbt, sbt;
11806
11807 st = &vtop->type;
11808 = dt->t & VT_BTYPE;
11809 sbt = st->t & VT_BTYPE;
11810 if (dt->t & VT_CONSTANT)
11811 warning("assignment of read-only location");
11812 switch(dbt) {
11813 case VT_PTR:
11814
11815
11816 if (is_null_pointer(vtop))
11817 goto type_ok;
11818
11819 if (is_integer_btype(sbt)) {
11820 warning("assignment makes pointer from integer without a cast");
11821 goto type_ok;
11822 }
11823 type1 = pointed_type(dt);
11824
11825 if (sbt == VT_FUNC) {
11826 if ((type1->t & VT_BTYPE) != VT_VOID &&
11827 !is_compatible_types(pointed_type(dt), st))
11828 goto error;
11829 else
11830 goto type_ok;
11831 }
11832 if (sbt != VT_PTR)
11833 goto error;
11834 type2 = pointed_type(st);
11835 if ((type1->t & VT_BTYPE) == VT_VOID ||
11836 (type2->t & VT_BTYPE) == VT_VOID) {
11837
11838 } else {
11839
11840 = *type1;
11841 tmp_type2 = *type2;
11842 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
11843 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
11844 if (!is_compatible_types(&tmp_type1, &tmp_type2))
11845 goto error;
11846 }
11847
11848 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
11849 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
11850 warning("assignment discards qualifiers from pointer target type");
11851 break;
11852 case VT_BYTE:
11853 case VT_SHORT:
11854 case VT_INT:
11855 case VT_LLONG:
11856 if (sbt == VT_PTR || sbt == VT_FUNC) {
11857 warning("assignment makes integer from pointer without a cast");
11858 }
11859
11860 break;
11861 case VT_STRUCT:
11862 tmp_type1 = *dt;
11863 tmp_type2 = *st;
11864 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
11865 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
11866 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
11867 error:
11868 type_to_str(buf1, sizeof(buf1), st, NULL);
11869 type_to_str(buf2, sizeof(buf2), dt, NULL);
11870 error("cannot cast '%s' to '%s'", buf1, buf2);
11871 }
11872 break;
11873 }
11874 type_ok:
11875 gen_cast(dt);
11876 }
11877
11878
11879 void vstore(void)
11880 {
11881 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
11882
11883 ft = vtop[-1].type.t;
11884 sbt = vtop->type.t & VT_BTYPE;
11885 dbt = ft & VT_BTYPE;
11886 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
11887 (sbt == VT_INT && dbt == VT_SHORT)) {
11888
11889 = VT_MUSTCAST;
11890 vtop->type.t = ft & VT_TYPE;
11891
11892 if (ft & VT_CONSTANT)
11893 warning("assignment of read-only location");
11894 } else {
11895 delayed_cast = 0;
11896 if (!(ft & VT_BITFIELD))
11897 gen_assign_cast(&vtop[-1].type);
11898 }
11899
11900 if (sbt == VT_STRUCT) {
11901
11902
11903
11904 if (!nocode_wanted) {
11905 size = type_size(&vtop->type, &align);
11906
11907 vpush_global_sym(&func_old_type, TOK_memcpy);
11908
11909
11910 (vtop - 2);
11911 vtop->type.t = VT_INT;
11912 gaddrof();
11913
11914 (vtop - 2);
11915 vtop->type.t = VT_INT;
11916 gaddrof();
11917
11918 (size);
11919 gfunc_call(3);
11920
11921 vswap();
11922 vpop();
11923 } else {
11924 vswap();
11925 vpop();
11926 }
11927
11928 } else if (ft & VT_BITFIELD) {
11929
11930 = (ft >> VT_STRUCT_SHIFT) & 0x3f;
11931 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
11932
11933 [-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
11934
11935
11936 ();
11937 vtop[-1] = vtop[-2];
11938
11939
11940 ((1 << bit_size) - 1);
11941 gen_op('&');
11942 vpushi(bit_pos);
11943 gen_op(TOK_SHL);
11944
11945 ();
11946 vpushi(~(((1 << bit_size) - 1) << bit_pos));
11947 gen_op('&');
11948 gen_op('|');
11949
11950 ();
11951 } else {
11952 #ifdef CONFIG_TCC_BCHECK
11953
11954 if (vtop[-1].r & VT_MUSTBOUND) {
11955 vswap();
11956 gbound();
11957 vswap();
11958 }
11959 #endif
11960 if (!nocode_wanted) {
11961 rc = RC_INT;
11962 if (is_float(ft))
11963 rc = RC_FLOAT;
11964 r = gv(rc);
11965
11966 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
11967 SValue sv;
11968 t = get_reg(RC_INT);
11969 sv.type.t = VT_INT;
11970 sv.r = VT_LOCAL | VT_LVAL;
11971 sv.c.ul = vtop[-1].c.ul;
11972 load(t, &sv);
11973 vtop[-1].r = t | VT_LVAL;
11974 }
11975 store(r, vtop - 1);
11976
11977 if ((ft & VT_BTYPE) == VT_LLONG) {
11978 vswap();
11979
11980 ->type.t = VT_INT;
11981 gaddrof();
11982 vpushi(4);
11983 gen_op('+');
11984 vtop->r |= VT_LVAL;
11985 vswap();
11986
11987 (vtop->r2, vtop - 1);
11988 }
11989 }
11990 vswap();
11991 vtop--;
11992 ->r |= delayed_cast;
11993 }
11994 }
11995
11996
11997 void inc(int post, int c)
11998 {
11999 test_lvalue();
12000 vdup();
12001 if (post) {
12002 gv_dup();
12003 (3);
12004 vrotb(3);
12005 }
12006
12007 (c - TOK_MID);
12008 gen_op('+');
12009 vstore();
12010 if (post)
12011 vpop();
12012 }
12013
12014
12015
12016
12017
12018
12019
12020
12021
12022 static void parse_attribute(AttributeDef *ad)
12023 {
12024 int t, n;
12025
12026 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
12027 next();
12028 skip('(');
12029 skip('(');
12030 while (tok != ')') {
12031 if (tok < TOK_IDENT)
12032 expect("attribute name");
12033 t = tok;
12034 next();
12035 switch(t) {
12036 case TOK_SECTION1:
12037 case TOK_SECTION2:
12038 skip('(');
12039 if (tok != TOK_STR)
12040 expect("section name");
12041 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
12042 next();
12043 skip(')');
12044 break;
12045 case TOK_ALIGNED1:
12046 case TOK_ALIGNED2:
12047 if (tok == '(') {
12048 next();
12049 n = expr_const();
12050 if (n <= 0 || (n & (n - 1)) != 0)
12051 error("alignment must be a positive power of two");
12052 skip(')');
12053 } else {
12054 n = MAX_ALIGN;
12055 }
12056 ad->aligned = n;
12057 break;
12058 case TOK_PACKED1:
12059 case TOK_PACKED2:
12060 ad->packed = 1;
12061 break;
12062 case TOK_UNUSED1:
12063 case TOK_UNUSED2:
12064
12065
12066 break;
12067 case TOK_NORETURN1:
12068 case TOK_NORETURN2:
12069
12070
12071 break;
12072 case TOK_CDECL1:
12073 case TOK_CDECL2:
12074 case TOK_CDECL3:
12075 ad->func_call = FUNC_CDECL;
12076 break;
12077 case TOK_STDCALL1:
12078 case TOK_STDCALL2:
12079 case TOK_STDCALL3:
12080 ad->func_call = FUNC_STDCALL;
12081 break;
12082 #ifdef TCC_TARGET_I386
12083 case TOK_REGPARM1:
12084 case TOK_REGPARM2:
12085 skip('(');
12086 n = expr_const();
12087 if (n > 3)
12088 n = 3;
12089 else if (n < 0)
12090 n = 0;
12091 if (n > 0)
12092 ad->func_call = FUNC_FASTCALL1 + n - 1;
12093 skip(')');
12094 break;
12095 #endif
12096 case TOK_DLLEXPORT:
12097 ad->dllexport = 1;
12098 break;
12099 default:
12100 if (tcc_state->warn_unsupported)
12101 warning("'%s' attribute ignored", get_tok_str(t, NULL));
12102
12103
12104 if (tok == '(') {
12105 next();
12106 while (tok != ')' && tok != -1)
12107 next();
12108 next();
12109 }
12110 break;
12111 }
12112 if (tok != ',')
12113 break;
12114 next();
12115 }
12116 skip(')');
12117 skip(')');
12118 }
12119 }
12120
12121
12122 static void struct_decl(CType *type, int u)
12123 {
12124 int a, v, size, align, maxalign, c, offset;
12125 int bit_size, bit_pos, bsize, bt, lbit_pos;
12126 Sym *s, *ss, **ps;
12127 AttributeDef ad;
12128 CType type1, btype;
12129
12130 a = tok;
12131 ();
12132 if (tok != '{') {
12133 v = tok;
12134 next();
12135
12136 if (v < TOK_IDENT)
12137 expect("struct/union/enum name");
12138 s = struct_find(v);
12139 if (s) {
12140 if (s->type.t != a)
12141 error("invalid type");
12142 goto do_decl;
12143 }
12144 } else {
12145 v = anon_sym++;
12146 }
12147 type1.t = a;
12148
12149 = sym_push(v | SYM_STRUCT, &type1, 0, -1);
12150 s->r = 0;
12151
12152 do_decl:
12153 type->t = u;
12154 type->ref = s;
12155
12156 if (tok == '{') {
12157 next();
12158 if (s->c != -1)
12159 error("struct/union/enum already defined");
12160
12161 = 0;
12162
12163 if (a == TOK_ENUM) {
12164 for(;;) {
12165 v = tok;
12166 if (v < TOK_UIDENT)
12167 expect("identifier");
12168 next();
12169 if (tok == '=') {
12170 next();
12171 c = expr_const();
12172 }
12173
12174 = sym_push(v, &int_type, VT_CONST, c);
12175 ss->type.t |= VT_STATIC;
12176 if (tok != ',')
12177 break;
12178 next();
12179 c++;
12180
12181 if (tok == '}')
12182 break;
12183 }
12184 skip('}');
12185 } else {
12186 maxalign = 1;
12187 ps = &s->next;
12188 bit_pos = 0;
12189 offset = 0;
12190 while (tok != '}') {
12191 parse_btype(&btype, &ad);
12192 while (1) {
12193 bit_size = -1;
12194 v = 0;
12195 type1 = btype;
12196 if (tok != ':') {
12197 type_decl(&type1, &ad, &v, TYPE_DIRECT);
12198 if ((type1.t & VT_BTYPE) == VT_FUNC ||
12199 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
12200 error("invalid type for '%s'",
12201 get_tok_str(v, NULL));
12202 }
12203 if (tok == ':') {
12204 next();
12205 bit_size = expr_const();
12206
12207 if (bit_size < 0)
12208 error("negative width in bit-field '%s'",
12209 get_tok_str(v, NULL));
12210 if (v && bit_size == 0)
12211 error("zero width for bit-field '%s'",
12212 get_tok_str(v, NULL));
12213 }
12214 size = type_size(&type1, &align);
12215 if (ad.aligned) {
12216 if (align < ad.aligned)
12217 align = ad.aligned;
12218 } else if (ad.packed) {
12219 align = 1;
12220 } else if (*tcc_state->pack_stack_ptr) {
12221 if (align > *tcc_state->pack_stack_ptr)
12222 align = *tcc_state->pack_stack_ptr;
12223 }
12224 lbit_pos = 0;
12225 if (bit_size >= 0) {
12226 bt = type1.t & VT_BTYPE;
12227 if (bt != VT_INT &&
12228 bt != VT_BYTE &&
12229 bt != VT_SHORT &&
12230 bt != VT_BOOL &&
12231 bt != VT_ENUM)
12232 error("bitfields must have scalar type");
12233 bsize = size * 8;
12234 if (bit_size > bsize) {
12235 error("width of '%s' exceeds its type",
12236 get_tok_str(v, NULL));
12237 } else if (bit_size == bsize) {
12238
12239 = 0;
12240 } else if (bit_size == 0) {
12241
12242
12243
12244 if (bit_pos > 0)
12245 bit_pos = bsize;
12246 } else {
12247
12248 if ((bit_pos + bit_size) > bsize)
12249 bit_pos = 0;
12250 lbit_pos = bit_pos;
12251
12252 .t |= VT_BITFIELD |
12253 (bit_pos << VT_STRUCT_SHIFT) |
12254 (bit_size << (VT_STRUCT_SHIFT + 6));
12255 bit_pos += bit_size;
12256 }
12257 } else {
12258 bit_pos = 0;
12259 }
12260 if (v) {
12261
12262
12263 if (lbit_pos == 0) {
12264 if (a == TOK_STRUCT) {
12265 c = (c + align - 1) & -align;
12266 offset = c;
12267 c += size;
12268 } else {
12269 offset = 0;
12270 if (size > c)
12271 c = size;
12272 }
12273 if (align > maxalign)
12274 maxalign = align;
12275 }
12276 #if 0
12277 printf("add field %s offset=%d",
12278 get_tok_str(v, NULL), offset);
12279 if (type1.t & VT_BITFIELD) {
12280 printf(" pos=%d size=%d",
12281 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
12282 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
12283 }
12284 printf("\n");
12285 #endif
12286 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
12287 *ps = ss;
12288 ps = &ss->next;
12289 }
12290 if (tok == ';' || tok == TOK_EOF)
12291 break;
12292 skip(',');
12293 }
12294 skip(';');
12295 }
12296 skip('}');
12297
12298 ->c = (c + maxalign - 1) & -maxalign;
12299 s->r = maxalign;
12300 }
12301 }
12302 }
12303
12304
12305
12306
12307 static int parse_btype(CType *type, AttributeDef *ad)
12308 {
12309 int t, u, type_found, typespec_found;
12310 Sym *s;
12311 CType type1;
12312
12313 memset(ad, 0, sizeof(AttributeDef));
12314 type_found = 0;
12315 typespec_found = 0;
12316 t = 0;
12317 while(1) {
12318 switch(tok) {
12319 case TOK_EXTENSION:
12320
12321 ();
12322 continue;
12323
12324
12325 case TOK_CHAR:
12326 u = VT_BYTE;
12327 basic_type:
12328 next();
12329 basic_type1:
12330 if ((t & VT_BTYPE) != 0)
12331 error("too many basic types");
12332 t |= u;
12333 typespec_found = 1;
12334 break;
12335 case TOK_VOID:
12336 u = VT_VOID;
12337 goto basic_type;
12338 case TOK_SHORT:
12339 u = VT_SHORT;
12340 goto basic_type;
12341 case TOK_INT:
12342 next();
12343 typespec_found = 1;
12344 break;
12345 case TOK_LONG:
12346 next();
12347 if ((t & VT_BTYPE) == VT_DOUBLE) {
12348 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
12349 } else if ((t & VT_BTYPE) == VT_LONG) {
12350 t = (t & ~VT_BTYPE) | VT_LLONG;
12351 } else {
12352 u = VT_LONG;
12353 goto basic_type1;
12354 }
12355 break;
12356 case TOK_BOOL:
12357 u = VT_BOOL;
12358 goto basic_type;
12359 case TOK_FLOAT:
12360 u = VT_FLOAT;
12361 goto basic_type;
12362 case TOK_DOUBLE:
12363 next();
12364 if ((t & VT_BTYPE) == VT_LONG) {
12365 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
12366 } else {
12367 u = VT_DOUBLE;
12368 goto basic_type1;
12369 }
12370 break;
12371 case TOK_ENUM:
12372 struct_decl(&type1, VT_ENUM);
12373 basic_type2:
12374 u = type1.t;
12375 type->ref = type1.ref;
12376 goto basic_type1;
12377 case TOK_STRUCT:
12378 case TOK_UNION:
12379 struct_decl(&type1, VT_STRUCT);
12380 goto basic_type2;
12381
12382
12383 case TOK_CONST1:
12384 case TOK_CONST2:
12385 case TOK_CONST3:
12386 t |= VT_CONSTANT;
12387 next();
12388 break;
12389 case TOK_VOLATILE1:
12390 case TOK_VOLATILE2:
12391 case TOK_VOLATILE3:
12392 t |= VT_VOLATILE;
12393 next();
12394 break;
12395 case TOK_SIGNED1:
12396 case TOK_SIGNED2:
12397 case TOK_SIGNED3:
12398 typespec_found = 1;
12399 t |= VT_SIGNED;
12400 next();
12401 break;
12402 case TOK_REGISTER:
12403 case TOK_AUTO:
12404 case TOK_RESTRICT1:
12405 case TOK_RESTRICT2:
12406 case TOK_RESTRICT3:
12407 next();
12408 break;
12409 case TOK_UNSIGNED:
12410 t |= VT_UNSIGNED;
12411 next();
12412 typespec_found = 1;
12413 break;
12414
12415
12416 case TOK_EXTERN:
12417 t |= VT_EXTERN;
12418 next();
12419 break;
12420 case TOK_STATIC:
12421 t |= VT_STATIC;
12422 next();
12423 break;
12424 case TOK_TYPEDEF:
12425 t |= VT_TYPEDEF;
12426 next();
12427 break;
12428 case TOK_INLINE1:
12429 case TOK_INLINE2:
12430 case TOK_INLINE3:
12431 t |= VT_INLINE;
12432 next();
12433 break;
12434
12435
12436 case TOK_ATTRIBUTE1:
12437 case TOK_ATTRIBUTE2:
12438 parse_attribute(ad);
12439 break;
12440
12441 case TOK_TYPEOF1:
12442 case TOK_TYPEOF2:
12443 case TOK_TYPEOF3:
12444 next();
12445 parse_expr_type(&type1);
12446 goto basic_type2;
12447 default:
12448 if (typespec_found)
12449 goto the_end;
12450 s = sym_find(tok);
12451 if (!s || !(s->type.t & VT_TYPEDEF))
12452 goto the_end;
12453 t |= (s->type.t & ~VT_TYPEDEF);
12454 type->ref = s->type.ref;
12455 next();
12456 break;
12457 }
12458 type_found = 1;
12459 }
12460 the_end:
12461 if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
12462 error("signed and unsigned modifier");
12463 if (tcc_state->char_is_unsigned) {
12464 if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
12465 t |= VT_UNSIGNED;
12466 }
12467 t &= ~VT_SIGNED;
12468
12469
12470 if ((t & VT_BTYPE) == VT_LONG)
12471 t = (t & ~VT_BTYPE) | VT_INT;
12472 type->t = t;
12473 return type_found;
12474 }
12475
12476
12477
12478 static inline void convert_parameter_type(CType *pt)
12479 {
12480
12481
12482 ->t &= ~(VT_CONSTANT | VT_VOLATILE);
12483
12484 ->t &= ~VT_ARRAY;
12485 if ((pt->t & VT_BTYPE) == VT_FUNC) {
12486 mk_pointer(pt);
12487 }
12488 }
12489
12490 static void post_type(CType *type, AttributeDef *ad)
12491 {
12492 int n, l, t1;
12493 Sym **plast, *s, *first;
12494 AttributeDef ad1;
12495 CType pt;
12496
12497 if (tok == '(') {
12498
12499 ();
12500 l = 0;
12501 first = NULL;
12502 plast = &first;
12503 while (tok != ')') {
12504
12505 if (l != FUNC_OLD) {
12506 if (!parse_btype(&pt, &ad1)) {
12507 if (l) {
12508 error("invalid type");
12509 } else {
12510 l = FUNC_OLD;
12511 goto old_proto;
12512 }
12513 }
12514 l = FUNC_NEW;
12515 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
12516 break;
12517 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
12518 if ((pt.t & VT_BTYPE) == VT_VOID)
12519 error("parameter declared as void");
12520 } else {
12521 old_proto:
12522 n = tok;
12523 pt.t = VT_INT;
12524 next();
12525 }
12526 convert_parameter_type(&pt);
12527 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
12528 *plast = s;
12529 plast = &s->next;
12530 if (tok == ',') {
12531 next();
12532 if (l == FUNC_NEW && tok == TOK_DOTS) {
12533 l = FUNC_ELLIPSIS;
12534 next();
12535 break;
12536 }
12537 }
12538 }
12539
12540 if (l == 0)
12541 l = FUNC_OLD;
12542 skip(')');
12543 t1 = type->t & VT_STORAGE;
12544
12545
12546 ->t &= ~(VT_STORAGE | VT_CONSTANT);
12547 post_type(type, ad);
12548
12549 = sym_push(SYM_FIELD, type, ad->func_call, l);
12550 s->next = first;
12551 type->t = t1 | VT_FUNC;
12552 type->ref = s;
12553 } else if (tok == '[') {
12554
12555 ();
12556 n = -1;
12557 if (tok != ']') {
12558 n = expr_const();
12559 if (n < 0)
12560 error("invalid array size");
12561 }
12562 skip(']');
12563
12564 = type->t & VT_STORAGE;
12565 type->t &= ~VT_STORAGE;
12566 post_type(type, ad);
12567
12568
12569
12570 = sym_push(SYM_FIELD, type, 0, n);
12571 type->t = t1 | VT_ARRAY | VT_PTR;
12572 type->ref = s;
12573 }
12574 }
12575
12576
12577
12578
12579
12580
12581
12582 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
12583 {
12584 Sym *s;
12585 CType type1, *type2;
12586 int qualifiers;
12587
12588 while (tok == '*') {
12589 qualifiers = 0;
12590 redo:
12591 next();
12592 switch(tok) {
12593 case TOK_CONST1:
12594 case TOK_CONST2:
12595 case TOK_CONST3:
12596 qualifiers |= VT_CONSTANT;
12597 goto redo;
12598 case TOK_VOLATILE1:
12599 case TOK_VOLATILE2:
12600 case TOK_VOLATILE3:
12601 qualifiers |= VT_VOLATILE;
12602 goto redo;
12603 case TOK_RESTRICT1:
12604 case TOK_RESTRICT2:
12605 case TOK_RESTRICT3:
12606 goto redo;
12607 }
12608 mk_pointer(type);
12609 type->t |= qualifiers;
12610 }
12611
12612
12613 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
12614 parse_attribute(ad);
12615
12616
12617
12618 .t = 0;
12619 if (tok == '(') {
12620 next();
12621
12622
12623 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
12624 parse_attribute(ad);
12625 type_decl(&type1, ad, v, td);
12626 skip(')');
12627 } else {
12628
12629 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
12630 *v = tok;
12631 next();
12632 } else {
12633 if (!(td & TYPE_ABSTRACT))
12634 expect("identifier");
12635 *v = 0;
12636 }
12637 }
12638 post_type(type, ad);
12639 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
12640 parse_attribute(ad);
12641 if (!type1.t)
12642 return;
12643
12644 = &type1;
12645 for(;;) {
12646 s = type2->ref;
12647 type2 = &s->type;
12648 if (!type2->t) {
12649 *type2 = *type;
12650 break;
12651 }
12652 }
12653 *type = type1;
12654 }
12655
12656
12657 static int lvalue_type(int t)
12658 {
12659 int bt, r;
12660 r = VT_LVAL;
12661 bt = t & VT_BTYPE;
12662 if (bt == VT_BYTE || bt == VT_BOOL)
12663 r |= VT_LVAL_BYTE;
12664 else if (bt == VT_SHORT)
12665 r |= VT_LVAL_SHORT;
12666 else
12667 return r;
12668 if (t & VT_UNSIGNED)
12669 r |= VT_LVAL_UNSIGNED;
12670 return r;
12671 }
12672
12673
12674 static void indir(void)
12675 {
12676 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
12677 expect("pointer");
12678 if ((vtop->r & VT_LVAL) && !nocode_wanted)
12679 gv(RC_INT);
12680 vtop->type = *pointed_type(&vtop->type);
12681
12682 if (!(vtop->type.t & VT_ARRAY)) {
12683 vtop->r |= lvalue_type(vtop->type.t);
12684
12685 if (do_bounds_check)
12686 vtop->r |= VT_MUSTBOUND;
12687 }
12688 }
12689
12690
12691 static void gfunc_param_typed(Sym *func, Sym *arg)
12692 {
12693 int func_type;
12694 CType type;
12695
12696 func_type = func->c;
12697 if (func_type == FUNC_OLD ||
12698 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
12699
12700 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
12701 type.t = VT_DOUBLE;
12702 gen_cast(&type);
12703 }
12704 } else if (arg == NULL) {
12705 error("too many arguments to function");
12706 } else {
12707 type = arg->type;
12708 type.t &= ~VT_CONSTANT;
12709 (&type);
12710 }
12711 }
12712
12713
12714
12715 static void parse_expr_type(CType *type)
12716 {
12717 int n;
12718 AttributeDef ad;
12719
12720 skip('(');
12721 if (parse_btype(type, &ad)) {
12722 type_decl(type, &ad, &n, TYPE_ABSTRACT);
12723 } else {
12724 expr_type(type);
12725 }
12726 skip(')');
12727 }
12728
12729 static void parse_type(CType *type)
12730 {
12731 AttributeDef ad;
12732 int n;
12733
12734 if (!parse_btype(type, &ad)) {
12735 expect("type");
12736 }
12737 type_decl(type, &ad, &n, TYPE_ABSTRACT);
12738 }
12739
12740 static void vpush_tokc(int t)
12741 {
12742 CType type;
12743 type.t = t;
12744 vsetc(&type, VT_CONST, &tokc);
12745 }
12746
12747 static void unary(void)
12748 {
12749 int n, t, align, size, r;
12750 CType type;
12751 Sym *s;
12752 AttributeDef ad;
12753
12754
12755
12756 tok_next:
12757 switch(tok) {
12758 case TOK_EXTENSION:
12759 next();
12760 goto tok_next;
12761 case TOK_CINT:
12762 case TOK_CCHAR:
12763 case TOK_LCHAR:
12764 vpushi(tokc.i);
12765 next();
12766 break;
12767 case TOK_CUINT:
12768 vpush_tokc(VT_INT | VT_UNSIGNED);
12769 next();
12770 break;
12771 case TOK_CLLONG:
12772 vpush_tokc(VT_LLONG);
12773 next();
12774 break;
12775 case TOK_CULLONG:
12776 vpush_tokc(VT_LLONG | VT_UNSIGNED);
12777 next();
12778 break;
12779 case TOK_CFLOAT:
12780 vpush_tokc(VT_FLOAT);
12781 next();
12782 break;
12783 case TOK_CDOUBLE:
12784 vpush_tokc(VT_DOUBLE);
12785 next();
12786 break;
12787 case TOK_CLDOUBLE:
12788 vpush_tokc(VT_LDOUBLE);
12789 next();
12790 break;
12791 case TOK___FUNCTION__:
12792 if (!gnu_ext)
12793 goto tok_identifier;
12794
12795 case TOK___FUNC__:
12796 {
12797 void *ptr;
12798 int len;
12799
12800 = strlen(funcname) + 1;
12801
12802 .t = VT_BYTE;
12803 mk_pointer(&type);
12804 type.t |= VT_ARRAY;
12805 type.ref->c = len;
12806 vpush_ref(&type, data_section, data_section->data_offset, len);
12807 ptr = section_ptr_add(data_section, len);
12808 memcpy(ptr, funcname, len);
12809 next();
12810 }
12811 break;
12812 case TOK_LSTR:
12813 t = VT_INT;
12814 goto str_init;
12815 case TOK_STR:
12816
12817 = VT_BYTE;
12818 str_init:
12819 if (tcc_state->warn_write_strings)
12820 t |= VT_CONSTANT;
12821 type.t = t;
12822 mk_pointer(&type);
12823 type.t |= VT_ARRAY;
12824 memset(&ad, 0, sizeof(AttributeDef));
12825 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
12826 break;
12827 case '(':
12828 next();
12829
12830 if (parse_btype(&type, &ad)) {
12831 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
12832 skip(')');
12833
12834 if (tok == '{') {
12835
12836 if (global_expr)
12837 r = VT_CONST;
12838 else
12839 r = VT_LOCAL;
12840
12841 if (!(type.t & VT_ARRAY))
12842 r |= lvalue_type(type.t);
12843 memset(&ad, 0, sizeof(AttributeDef));
12844 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
12845 } else {
12846 unary();
12847 gen_cast(&type);
12848 }
12849 } else if (tok == '{') {
12850
12851 (0);
12852
12853
12854 (NULL, NULL, NULL, NULL, 0, 1);
12855 skip(')');
12856 } else {
12857 gexpr();
12858 skip(')');
12859 }
12860 break;
12861 case '*':
12862 next();
12863 unary();
12864 indir();
12865 break;
12866 case '&':
12867 next();
12868 unary();
12869
12870
12871
12872
12873
12874 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
12875 !(vtop->type.t & VT_ARRAY))
12876 test_lvalue();
12877 mk_pointer(&vtop->type);
12878 gaddrof();
12879 break;
12880 case '!':
12881 next();
12882 unary();
12883 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST)
12884 vtop->c.i = !vtop->c.i;
12885 else if ((vtop->r & VT_VALMASK) == VT_CMP)
12886 vtop->c.i = vtop->c.i ^ 1;
12887 else
12888 vseti(VT_JMP, gtst(1, 0));
12889 break;
12890 case '~':
12891 next();
12892 unary();
12893 vpushi(-1);
12894 gen_op('^');
12895 break;
12896 case '+':
12897 next();
12898
12899 ();
12900 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
12901 error("pointer not accepted for unary plus");
12902 vpushi(0);
12903 gen_op('+');
12904 break;
12905 case TOK_SIZEOF:
12906 case TOK_ALIGNOF1:
12907 case TOK_ALIGNOF2:
12908 t = tok;
12909 next();
12910 if (tok == '(') {
12911 parse_expr_type(&type);
12912 } else {
12913 unary_type(&type);
12914 }
12915 size = type_size(&type, &align);
12916 if (t == TOK_SIZEOF) {
12917 if (size < 0)
12918 error("sizeof applied to an incomplete type");
12919 vpushi(size);
12920 } else {
12921 vpushi(align);
12922 }
12923 break;
12924
12925 case TOK_builtin_types_compatible_p:
12926 {
12927 CType type1, type2;
12928 next();
12929 skip('(');
12930 parse_type(&type1);
12931 skip(',');
12932 parse_type(&type2);
12933 skip(')');
12934 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
12935 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
12936 vpushi(is_compatible_types(&type1, &type2));
12937 }
12938 break;
12939 case TOK_builtin_constant_p:
12940 {
12941 int saved_nocode_wanted, res;
12942 next();
12943 skip('(');
12944 saved_nocode_wanted = nocode_wanted;
12945 nocode_wanted = 1;
12946 gexpr();
12947 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
12948 vpop();
12949 nocode_wanted = saved_nocode_wanted;
12950 skip(')');
12951 vpushi(res);
12952 }
12953 break;
12954 case TOK_INC:
12955 case TOK_DEC:
12956 t = tok;
12957 next();
12958 unary();
12959 inc(0, t);
12960 break;
12961 case '-':
12962 next();
12963 vpushi(0);
12964 unary();
12965 gen_op('-');
12966 break;
12967 case TOK_LAND:
12968 if (!gnu_ext)
12969 goto tok_identifier;
12970 next();
12971
12972 if (tok < TOK_UIDENT)
12973 expect("label identifier");
12974 s = label_find(tok);
12975 if (!s) {
12976 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
12977 } else {
12978 if (s->r == LABEL_DECLARED)
12979 s->r = LABEL_FORWARD;
12980 }
12981 if (!s->type.t) {
12982 s->type.t = VT_VOID;
12983 mk_pointer(&s->type);
12984 s->type.t |= VT_STATIC;
12985 }
12986 vset(&s->type, VT_CONST | VT_SYM, 0);
12987 vtop->sym = s;
12988 next();
12989 break;
12990 default:
12991 tok_identifier:
12992 t = tok;
12993 next();
12994 if (t < TOK_UIDENT)
12995 expect("identifier");
12996 s = sym_find(t);
12997 if (!s) {
12998 if (tok != '(')
12999 error("'%s' undeclared", get_tok_str(t, NULL));
13000
13001
13002 if (tcc_state->warn_implicit_function_declaration)
13003 warning("implicit declaration of function '%s'",
13004 get_tok_str(t, NULL));
13005 s = external_global_sym(t, &func_old_type, 0);
13006 }
13007 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
13008 (VT_STATIC | VT_INLINE | VT_FUNC)) {
13009
13010
13011
13012
13013
13014 if (!s->c)
13015 put_extern_sym(s, text_section, 0, 0);
13016 r = VT_SYM | VT_CONST;
13017 } else {
13018 r = s->r;
13019 }
13020 vset(&s->type, r, s->c);
13021
13022 if (vtop->r & VT_SYM) {
13023 vtop->sym = s;
13024 vtop->c.ul = 0;
13025 }
13026 break;
13027 }
13028
13029
13030 while (1) {
13031 if (tok == TOK_INC || tok == TOK_DEC) {
13032 inc(1, tok);
13033 next();
13034 } else if (tok == '.' || tok == TOK_ARROW) {
13035
13036 if (tok == TOK_ARROW)
13037 indir();
13038 test_lvalue();
13039 gaddrof();
13040 next();
13041
13042 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
13043 expect("struct or union");
13044 s = vtop->type.ref;
13045
13046 |= SYM_FIELD;
13047 while ((s = s->next) != NULL) {
13048 if (s->v == tok)
13049 break;
13050 }
13051 if (!s)
13052 error("field not found");
13053
13054 ->type = char_pointer_type;
13055 (s->c);
13056 gen_op('+');
13057
13058 ->type = s->type;
13059
13060 if (!(vtop->type.t & VT_ARRAY)) {
13061 vtop->r |= lvalue_type(vtop->type.t);
13062
13063 if (do_bounds_check)
13064 vtop->r |= VT_MUSTBOUND;
13065 }
13066 next();
13067 } else if (tok == '[') {
13068 next();
13069 gexpr();
13070 gen_op('+');
13071 indir();
13072 skip(']');
13073 } else if (tok == '(') {
13074 SValue ret;
13075 Sym *sa;
13076 int nb_args;
13077
13078
13079 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
13080
13081 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
13082 vtop->type = *pointed_type(&vtop->type);
13083 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
13084 goto error_func;
13085 } else {
13086 error_func:
13087 expect("function pointer");
13088 }
13089 } else {
13090 vtop->r &= ~VT_LVAL;
13091 }
13092
13093 = vtop->type.ref;
13094 next();
13095 sa = s->next;
13096 = 0;
13097
13098 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
13099
13100 = type_size(&s->type, &align);
13101 loc = (loc - size) & -align;
13102 ret.type = s->type;
13103 ret.r = VT_LOCAL | VT_LVAL;
13104
13105
13106 (VT_LOCAL, loc);
13107 ret.c = vtop->c;
13108 nb_args++;
13109 } else {
13110 ret.type = s->type;
13111 ret.r2 = VT_CONST;
13112
13113 if (is_float(ret.type.t)) {
13114 ret.r = REG_FRET;
13115 } else {
13116 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
13117 ret.r2 = REG_LRET;
13118 ret.r = REG_IRET;
13119 }
13120 ret.c.i = 0;
13121 }
13122 if (tok != ')') {
13123 for(;;) {
13124 expr_eq();
13125 gfunc_param_typed(s, sa);
13126 nb_args++;
13127 if (sa)
13128 sa = sa->next;
13129 if (tok == ')')
13130 break;
13131 skip(',');
13132 }
13133 }
13134 if (sa)
13135 error("too few arguments to function");
13136 skip(')');
13137 if (!nocode_wanted) {
13138 gfunc_call(nb_args);
13139 } else {
13140 vtop -= (nb_args + 1);
13141 }
13142
13143 (&ret.type, ret.r, &ret.c);
13144 vtop->r2 = ret.r2;
13145 } else {
13146 break;
13147 }
13148 }
13149 }
13150
13151 static void uneq(void)
13152 {
13153 int t;
13154
13155 unary();
13156 if (tok == '=' ||
13157 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
13158 tok == TOK_A_XOR || tok == TOK_A_OR ||
13159 tok == TOK_A_SHL || tok == TOK_A_SAR) {
13160 test_lvalue();
13161 t = tok;
13162 next();
13163 if (t == '=') {
13164 expr_eq();
13165 } else {
13166 vdup();
13167 expr_eq();
13168 gen_op(t & 0x7f);
13169 }
13170 vstore();
13171 }
13172 }
13173
13174 static void expr_prod(void)
13175 {
13176 int t;
13177
13178 uneq();
13179 while (tok == '*' || tok == '/' || tok == '%') {
13180 t = tok;
13181 next();
13182 uneq();
13183 gen_op(t);
13184 }
13185 }
13186
13187 static void expr_sum(void)
13188 {
13189 int t;
13190
13191 expr_prod();
13192 while (tok == '+' || tok == '-') {
13193 t = tok;
13194 next();
13195 expr_prod();
13196 gen_op(t);
13197 }
13198 }
13199
13200 static void expr_shift(void)
13201 {
13202 int t;
13203
13204 expr_sum();
13205 while (tok == TOK_SHL || tok == TOK_SAR) {
13206 t = tok;
13207 next();
13208 expr_sum();
13209 gen_op(t);
13210 }
13211 }
13212
13213 static void expr_cmp(void)
13214 {
13215 int t;
13216
13217 expr_shift();
13218 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
13219 tok == TOK_ULT || tok == TOK_UGE) {
13220 t = tok;
13221 next();
13222 expr_shift();
13223 gen_op(t);
13224 }
13225 }
13226
13227 static void expr_cmpeq(void)
13228 {
13229 int t;
13230
13231 expr_cmp();
13232 while (tok == TOK_EQ || tok == TOK_NE) {
13233 t = tok;
13234 next();
13235 expr_cmp();
13236 gen_op(t);
13237 }
13238 }
13239
13240 static void expr_and(void)
13241 {
13242 expr_cmpeq();
13243 while (tok == '&') {
13244 next();
13245 expr_cmpeq();
13246 gen_op('&');
13247 }
13248 }
13249
13250 static void expr_xor(void)
13251 {
13252 expr_and();
13253 while (tok == '^') {
13254 next();
13255 expr_and();
13256 gen_op('^');
13257 }
13258 }
13259
13260 static void expr_or(void)
13261 {
13262 expr_xor();
13263 while (tok == '|') {
13264 next();
13265 expr_xor();
13266 gen_op('|');
13267 }
13268 }
13269
13270
13271 static void expr_land_const(void)
13272 {
13273 expr_or();
13274 while (tok == TOK_LAND) {
13275 next();
13276 expr_or();
13277 gen_op(TOK_LAND);
13278 }
13279 }
13280
13281
13282 static void expr_lor_const(void)
13283 {
13284 expr_land_const();
13285 while (tok == TOK_LOR) {
13286 next();
13287 expr_land_const();
13288 gen_op(TOK_LOR);
13289 }
13290 }
13291
13292
13293 static void expr_land(void)
13294 {
13295 int t;
13296
13297 expr_or();
13298 if (tok == TOK_LAND) {
13299 t = 0;
13300 for(;;) {
13301 t = gtst(1, t);
13302 if (tok != TOK_LAND) {
13303 vseti(VT_JMPI, t);
13304 break;
13305 }
13306 next();
13307 expr_or();
13308 }
13309 }
13310 }
13311
13312 static void expr_lor(void)
13313 {
13314 int t;
13315
13316 expr_land();
13317 if (tok == TOK_LOR) {
13318 t = 0;
13319 for(;;) {
13320 t = gtst(0, t);
13321 if (tok != TOK_LOR) {
13322 vseti(VT_JMP, t);
13323 break;
13324 }
13325 next();
13326 expr_land();
13327 }
13328 }
13329 }
13330
13331
13332 static void expr_eq(void)
13333 {
13334 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
13335 SValue sv;
13336 CType type, type1, type2;
13337
13338 if (const_wanted) {
13339 int c1, c;
13340 expr_lor_const();
13341 if (tok == '?') {
13342 c = vtop->c.i;
13343 vpop();
13344 next();
13345 if (tok == ':' && gnu_ext) {
13346 c1 = c;
13347 } else {
13348 gexpr();
13349 c1 = vtop->c.i;
13350 vpop();
13351 }
13352 skip(':');
13353 expr_eq();
13354 if (c)
13355 vtop->c.i = c1;
13356 }
13357 } else {
13358 expr_lor();
13359 if (tok == '?') {
13360 next();
13361 if (vtop != vstack) {
13362
13363
13364 if (is_float(vtop->type.t))
13365 rc = RC_FLOAT;
13366 else
13367 rc = RC_INT;
13368 gv(rc);
13369 save_regs(1);
13370 }
13371 if (tok == ':' && gnu_ext) {
13372 gv_dup();
13373 tt = gtst(1, 0);
13374 } else {
13375 tt = gtst(1, 0);
13376 gexpr();
13377 }
13378 type1 = vtop->type;
13379 sv = *vtop;
13380 --;
13381 (':');
13382 u = gjmp(0);
13383 gsym(tt);
13384 expr_eq();
13385 type2 = vtop->type;
13386
13387 t1 = type1.t;
13388 bt1 = t1 & VT_BTYPE;
13389 t2 = type2.t;
13390 bt2 = t2 & VT_BTYPE;
13391
13392 if (is_float(bt1) || is_float(bt2)) {
13393 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
13394 type.t = VT_LDOUBLE;
13395 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
13396 type.t = VT_DOUBLE;
13397 } else {
13398 type.t = VT_FLOAT;
13399 }
13400 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
13401
13402 .t = VT_LLONG;
13403
13404 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
13405 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
13406 type.t |= VT_UNSIGNED;
13407 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
13408
13409 = type1;
13410 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
13411
13412 = type1;
13413 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
13414
13415 .t = VT_VOID;
13416 } else {
13417
13418 .t = VT_INT;
13419
13420 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
13421 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
13422 type.t |= VT_UNSIGNED;
13423 }
13424
13425
13426 (&type);
13427 rc = RC_INT;
13428 if (is_float(type.t)) {
13429 rc = RC_FLOAT;
13430 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
13431
13432
13433 = RC_IRET;
13434 }
13435
13436 r2 = gv(rc);
13437
13438
13439 = gjmp(0);
13440 gsym(u);
13441
13442 *vtop = sv;
13443 gen_cast(&type);
13444 r1 = gv(rc);
13445 move_reg(r2, r1);
13446 vtop->r = r2;
13447 gsym(tt);
13448 }
13449 }
13450 }
13451
13452 static void gexpr(void)
13453 {
13454 while (1) {
13455 expr_eq();
13456 if (tok != ',')
13457 break;
13458 vpop();
13459 next();
13460 }
13461 }
13462
13463
13464 static void expr_type(CType *type)
13465 {
13466 int saved_nocode_wanted;
13467
13468 saved_nocode_wanted = nocode_wanted;
13469 nocode_wanted = 1;
13470 gexpr();
13471 *type = vtop->type;
13472 vpop();
13473 nocode_wanted = saved_nocode_wanted;
13474 }
13475
13476
13477
13478 static void unary_type(CType *type)
13479 {
13480 int a;
13481
13482 a = nocode_wanted;
13483 nocode_wanted = 1;
13484 unary();
13485 *type = vtop->type;
13486 vpop();
13487 nocode_wanted = a;
13488 }
13489
13490
13491 static void expr_const1(void)
13492 {
13493 int a;
13494 a = const_wanted;
13495 const_wanted = 1;
13496 expr_eq();
13497 const_wanted = a;
13498 }
13499
13500
13501 static int expr_const(void)
13502 {
13503 int c;
13504 expr_const1();
13505 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
13506 expect("constant expression");
13507 c = vtop->c.i;
13508 vpop();
13509 return c;
13510 }
13511
13512
13513
13514 static int is_label(void)
13515 {
13516 int last_tok;
13517
13518
13519 if (tok < TOK_UIDENT)
13520 return 0;
13521
13522 = tok;
13523 next();
13524 if (tok == ':') {
13525 next();
13526 return last_tok;
13527 } else {
13528 unget_tok(last_tok);
13529 return 0;
13530 }
13531 }
13532
13533 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
13534 int case_reg, int is_expr)
13535 {
13536 int a, b, c, d;
13537 Sym *s;
13538
13539
13540 if (do_debug &&
13541 (last_line_num != file->line_num || last_ind != ind)) {
13542 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
13543 last_ind = ind;
13544 last_line_num = file->line_num;
13545 }
13546
13547 if (is_expr) {
13548
13549 (0);
13550 vtop->type.t = VT_VOID;
13551 }
13552
13553 if (tok == TOK_IF) {
13554
13555 ();
13556 skip('(');
13557 gexpr();
13558 skip(')');
13559 a = gtst(1, 0);
13560 block(bsym, csym, case_sym, def_sym, case_reg, 0);
13561 c = tok;
13562 if (c == TOK_ELSE) {
13563 next();
13564 d = gjmp(0);
13565 gsym(a);
13566 block(bsym, csym, case_sym, def_sym, case_reg, 0);
13567 gsym(d);
13568 } else
13569 gsym(a);
13570 } else if (tok == TOK_WHILE) {
13571 next();
13572 d = ind;
13573 skip('(');
13574 gexpr();
13575 skip(')');
13576 a = gtst(1, 0);
13577 b = 0;
13578 block(&a, &b, case_sym, def_sym, case_reg, 0);
13579 gjmp_addr(d);
13580 gsym(a);
13581 gsym_addr(b, d);
13582 } else if (tok == '{') {
13583 Sym *llabel;
13584
13585 next();
13586
13587 = local_stack;
13588 llabel = local_label_stack;
13589
13590 if (tok == TOK_LABEL) {
13591 next();
13592 for(;;) {
13593 if (tok < TOK_UIDENT)
13594 expect("label identifier");
13595 label_push(&local_label_stack, tok, LABEL_DECLARED);
13596 next();
13597 if (tok == ',') {
13598 next();
13599 } else {
13600 skip(';');
13601 break;
13602 }
13603 }
13604 }
13605 while (tok != '}') {
13606 decl(VT_LOCAL);
13607 if (tok != '}') {
13608 if (is_expr)
13609 vpop();
13610 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
13611 }
13612 }
13613
13614 (&local_label_stack, llabel);
13615
13616 (&local_stack, s);
13617 next();
13618 } else if (tok == TOK_RETURN) {
13619 next();
13620 if (tok != ';') {
13621 gexpr();
13622 gen_assign_cast(&func_vt);
13623 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
13624 CType type;
13625
13626
13627 = func_vt;
13628 mk_pointer(&type);
13629 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
13630 indir();
13631 vswap();
13632
13633 ();
13634 } else if (is_float(func_vt.t)) {
13635 gv(RC_FRET);
13636 } else {
13637 gv(RC_IRET);
13638 }
13639 vtop--;
13640 }
13641 skip(';');
13642 rsym = gjmp(rsym);
13643 } else if (tok == TOK_BREAK) {
13644
13645 if (!bsym)
13646 error("cannot break");
13647 *bsym = gjmp(*bsym);
13648 next();
13649 skip(';');
13650 } else if (tok == TOK_CONTINUE) {
13651
13652 if (!csym)
13653 error("cannot continue");
13654 *csym = gjmp(*csym);
13655 next();
13656 skip(';');
13657 } else if (tok == TOK_FOR) {
13658 int e;
13659 next();
13660 skip('(');
13661 if (tok != ';') {
13662 gexpr();
13663 vpop();
13664 }
13665 skip(';');
13666 d = ind;
13667 c = ind;
13668 a = 0;
13669 b = 0;
13670 if (tok != ';') {
13671 gexpr();
13672 a = gtst(1, 0);
13673 }
13674 skip(';');
13675 if (tok != ')') {
13676 e = gjmp(0);
13677 c = ind;
13678 gexpr();
13679 vpop();
13680 gjmp_addr(d);
13681 gsym(e);
13682 }
13683 skip(')');
13684 block(&a, &b, case_sym, def_sym, case_reg, 0);
13685 gjmp_addr(c);
13686 gsym(a);
13687 gsym_addr(b, c);
13688 } else
13689 if (tok == TOK_DO) {
13690 next();
13691 a = 0;
13692 b = 0;
13693 d = ind;
13694 block(&a, &b, case_sym, def_sym, case_reg, 0);
13695 skip(TOK_WHILE);
13696 skip('(');
13697 gsym(b);
13698 gexpr();
13699 c = gtst(0, 0);
13700 gsym_addr(c, d);
13701 skip(')');
13702 gsym(a);
13703 skip(';');
13704 } else
13705 if (tok == TOK_SWITCH) {
13706 next();
13707 skip('(');
13708 gexpr();
13709
13710 = gv(RC_INT);
13711 vpop();
13712 skip(')');
13713 a = 0;
13714 b = gjmp(0);
13715 = 0;
13716 block(&a, csym, &b, &c, case_reg, 0);
13717
13718 if (c == 0)
13719 c = ind;
13720
13721 (b, c);
13722
13723 (a);
13724 } else
13725 if (tok == TOK_CASE) {
13726 int v1, v2;
13727 if (!case_sym)
13728 expect("switch");
13729 next();
13730 v1 = expr_const();
13731 v2 = v1;
13732 if (gnu_ext && tok == TOK_DOTS) {
13733 next();
13734 v2 = expr_const();
13735 if (v2 < v1)
13736 warning("empty case range");
13737 }
13738
13739 = gjmp(0);
13740 gsym(*case_sym);
13741 vseti(case_reg, 0);
13742 vpushi(v1);
13743 if (v1 == v2) {
13744 gen_op(TOK_EQ);
13745 *case_sym = gtst(1, 0);
13746 } else {
13747 gen_op(TOK_GE);
13748 *case_sym = gtst(1, 0);
13749 vseti(case_reg, 0);
13750 vpushi(v2);
13751 gen_op(TOK_LE);
13752 *case_sym = gtst(1, *case_sym);
13753 }
13754 gsym(b);
13755 skip(':');
13756 is_expr = 0;
13757 goto block_after_label;
13758 } else
13759 if (tok == TOK_DEFAULT) {
13760 next();
13761 skip(':');
13762 if (!def_sym)
13763 expect("switch");
13764 if (*def_sym)
13765 error("too many 'default'");
13766 *def_sym = ind;
13767 is_expr = 0;
13768 goto block_after_label;
13769 } else
13770 if (tok == TOK_GOTO) {
13771 next();
13772 if (tok == '*' && gnu_ext) {
13773
13774 ();
13775 gexpr();
13776 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
13777 expect("pointer");
13778 ggoto();
13779 } else if (tok >= TOK_UIDENT) {
13780 s = label_find(tok);
13781
13782 if (!s) {
13783 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
13784 } else {
13785 if (s->r == LABEL_DECLARED)
13786 s->r = LABEL_FORWARD;
13787 }
13788
13789 if (s->r & LABEL_FORWARD)
13790 s->next = (void *)gjmp((long)s->next);
13791 else
13792 gjmp_addr((long)s->next);
13793 next();
13794 } else {
13795 expect("label identifier");
13796 }
13797 skip(';');
13798 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
13799 asm_instr();
13800 } else {
13801 b = is_label();
13802 if (b) {
13803
13804 = label_find(b);
13805 if (s) {
13806 if (s->r == LABEL_DEFINED)
13807 error("duplicate label '%s'", get_tok_str(s->v, NULL));
13808 gsym((long)s->next);
13809 s->r = LABEL_DEFINED;
13810 } else {
13811 s = label_push(&global_label_stack, b, LABEL_DEFINED);
13812 }
13813 s->next = (void *)ind;
13814
13815 block_after_label:
13816 if (tok == '}') {
13817 warning("deprecated use of label at end of compound statement");
13818 } else {
13819 if (is_expr)
13820 vpop();
13821 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
13822 }
13823 } else {
13824
13825 if (tok != ';') {
13826 if (is_expr) {
13827 vpop();
13828 gexpr();
13829 } else {
13830 gexpr();
13831 vpop();
13832 }
13833 }
13834 skip(';');
13835 }
13836 }
13837 }
13838
13839
13840
13841
13842
13843 static void decl_designator(CType *type, Section *sec, unsigned long c,
13844 int *cur_index, Sym **cur_field,
13845 int size_only)
13846 {
13847 Sym *s, *f;
13848 int notfirst, index, index_last, align, l, nb_elems, elem_size;
13849 CType type1;
13850
13851 notfirst = 0;
13852 elem_size = 0;
13853 nb_elems = 1;
13854 if (gnu_ext && (l = is_label()) != 0)
13855 goto struct_field;
13856 while (tok == '[' || tok == '.') {
13857 if (tok == '[') {
13858 if (!(type->t & VT_ARRAY))
13859 expect("array type");
13860 s = type->ref;
13861 next();
13862 index = expr_const();
13863 if (index < 0 || (s->c >= 0 && index >= s->c))
13864 expect("invalid index");
13865 if (tok == TOK_DOTS && gnu_ext) {
13866 next();
13867 index_last = expr_const();
13868 if (index_last < 0 ||
13869 (s->c >= 0 && index_last >= s->c) ||
13870 index_last < index)
13871 expect("invalid index");
13872 } else {
13873 index_last = index;
13874 }
13875 skip(']');
13876 if (!notfirst)
13877 *cur_index = index_last;
13878 type = pointed_type(type);
13879 elem_size = type_size(type, &align);
13880 c += index * elem_size;
13881
13882 = index_last - index + 1;
13883 if (nb_elems != 1) {
13884 notfirst = 1;
13885 break;
13886 }
13887 } else {
13888 next();
13889 l = tok;
13890 next();
13891 struct_field:
13892 if ((type->t & VT_BTYPE) != VT_STRUCT)
13893 expect("struct/union type");
13894 s = type->ref;
13895 l |= SYM_FIELD;
13896 f = s->next;
13897 while (f) {
13898 if (f->v == l)
13899 break;
13900 f = f->next;
13901 }
13902 if (!f)
13903 expect("field");
13904 if (!notfirst)
13905 *cur_field = f;
13906
13907 = f->type;
13908 type1.t |= (type->t & ~VT_TYPE);
13909 type = &type1;
13910 c += f->c;
13911 }
13912 notfirst = 1;
13913 }
13914 if (notfirst) {
13915 if (tok == '=') {
13916 next();
13917 } else {
13918 if (!gnu_ext)
13919 expect("=");
13920 }
13921 } else {
13922 if (type->t & VT_ARRAY) {
13923 index = *cur_index;
13924 type = pointed_type(type);
13925 c += index * type_size(type, &align);
13926 } else {
13927 f = *cur_field;
13928 if (!f)
13929 error("too many field init");
13930
13931 = f->type;
13932 type1.t |= (type->t & ~VT_TYPE);
13933 type = &type1;
13934 c += f->c;
13935 }
13936 }
13937 decl_initializer(type, sec, c, 0, size_only);
13938
13939
13940 if (!size_only && nb_elems > 1) {
13941 unsigned long c_end;
13942 uint8_t *src, *dst;
13943 int i;
13944
13945 if (!sec)
13946 error("range init not supported yet for dynamic storage");
13947 c_end = c + nb_elems * elem_size;
13948 if (c_end > sec->data_allocated)
13949 section_realloc(sec, c_end);
13950 src = sec->data + c;
13951 dst = src;
13952 for(i = 1; i < nb_elems; i++) {
13953 dst += elem_size;
13954 memcpy(dst, src, elem_size);
13955 }
13956 }
13957 }
13958
13959 #define EXPR_VAL 0
13960 #define EXPR_CONST 1
13961 #define EXPR_ANY 2
13962
13963
13964 static void init_putv(CType *type, Section *sec, unsigned long c,
13965 int v, int expr_type)
13966 {
13967 int saved_global_expr, bt, bit_pos, bit_size;
13968 void *ptr;
13969 unsigned long long bit_mask;
13970 CType dtype;
13971
13972 switch(expr_type) {
13973 case EXPR_VAL:
13974 vpushi(v);
13975 break;
13976 case EXPR_CONST:
13977
13978 = global_expr;
13979 global_expr = 1;
13980 expr_const1();
13981 global_expr = saved_global_expr;
13982
13983 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
13984 error("initializer element is not constant");
13985 break;
13986 case EXPR_ANY:
13987 expr_eq();
13988 break;
13989 }
13990
13991 dtype = *type;
13992 dtype.t &= ~VT_CONSTANT;
13993
13994 if (sec) {
13995
13996
13997 (&dtype);
13998 bt = type->t & VT_BTYPE;
13999 ptr = sec->data + c;
14000
14001 if (!(type->t & VT_BITFIELD)) {
14002 bit_pos = 0;
14003 bit_size = 32;
14004 bit_mask = -1LL;
14005 } else {
14006 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
14007 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
14008 bit_mask = (1LL << bit_size) - 1;
14009 }
14010 if ((vtop->r & VT_SYM) &&
14011 (bt == VT_BYTE ||
14012 bt == VT_SHORT ||
14013 bt == VT_DOUBLE ||
14014 bt == VT_LDOUBLE ||
14015 bt == VT_LLONG ||
14016 (bt == VT_INT && bit_size != 32)))
14017 error("initializer element is not computable at load time");
14018 switch(bt) {
14019 case VT_BYTE:
14020 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
14021 break;
14022 case VT_SHORT:
14023 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
14024 break;
14025 case VT_DOUBLE:
14026 *(double *)ptr = vtop->c.d;
14027 break;
14028 case VT_LDOUBLE:
14029 *(long double *)ptr = vtop->c.ld;
14030 break;
14031 case VT_LLONG:
14032 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
14033 break;
14034 default:
14035 if (vtop->r & VT_SYM) {
14036 greloc(sec, vtop->sym, c, R_DATA_32);
14037 }
14038 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
14039 break;
14040 }
14041 vtop--;
14042 } else {
14043 vset(&dtype, VT_LOCAL, c);
14044 vswap();
14045 vstore();
14046 vpop();
14047 }
14048 }
14049
14050
14051 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
14052 {
14053 if (sec) {
14054
14055 } else {
14056 vpush_global_sym(&func_old_type, TOK_memset);
14057 vseti(VT_LOCAL, c);
14058 vpushi(0);
14059 vpushi(size);
14060 gfunc_call(3);
14061 }
14062 }
14063
14064
14065
14066
14067
14068
14069 static void decl_initializer(CType *type, Section *sec, unsigned long c,
14070 int first, int size_only)
14071 {
14072 int index, array_length, n, no_oblock, nb, parlevel, i;
14073 int size1, align1, expr_type;
14074 Sym *s, *f;
14075 CType *t1;
14076
14077 if (type->t & VT_ARRAY) {
14078 s = type->ref;
14079 n = s->c;
14080 array_length = 0;
14081 t1 = pointed_type(type);
14082 size1 = type_size(t1, &align1);
14083
14084 no_oblock = 1;
14085 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
14086 tok == '{') {
14087 skip('{');
14088 no_oblock = 0;
14089 }
14090
14091
14092
14093 if ((tok == TOK_LSTR &&
14094 (t1->t & VT_BTYPE) == VT_INT) ||
14095 (tok == TOK_STR &&
14096 (t1->t & VT_BTYPE) == VT_BYTE)) {
14097 while (tok == TOK_STR || tok == TOK_LSTR) {
14098 int cstr_len, ch;
14099 CString *cstr;
14100
14101 cstr = tokc.cstr;
14102
14103 if (tok == TOK_STR)
14104 cstr_len = cstr->size;
14105 else
14106 cstr_len = cstr->size / sizeof(int);
14107 cstr_len--;
14108 nb = cstr_len;
14109 if (n >= 0 && nb > (n - array_length))
14110 nb = n - array_length;
14111 if (!size_only) {
14112 if (cstr_len > nb)
14113 warning("initializer-string for array is too long");
14114
14115
14116
14117 if (sec && tok == TOK_STR && size1 == 1) {
14118 memcpy(sec->data + c + array_length, cstr->data, nb);
14119 } else {
14120 for(i=0;i<nb;i++) {
14121 if (tok == TOK_STR)
14122 ch = ((unsigned char *)cstr->data)[i];
14123 else
14124 ch = ((int *)cstr->data)[i];
14125 init_putv(t1, sec, c + (array_length + i) * size1,
14126 ch, EXPR_VAL);
14127 }
14128 }
14129 }
14130 array_length += nb;
14131 next();
14132 }
14133
14134
14135 if (n < 0 || array_length < n) {
14136 if (!size_only) {
14137 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
14138 }
14139 array_length++;
14140 }
14141 } else {
14142 index = 0;
14143 while (tok != '}') {
14144 decl_designator(type, sec, c, &index, NULL, size_only);
14145 if (n >= 0 && index >= n)
14146 error("index too large");
14147
14148
14149 if (!size_only && array_length < index) {
14150 init_putz(t1, sec, c + array_length * size1,
14151 (index - array_length) * size1);
14152 }
14153 index++;
14154 if (index > array_length)
14155 array_length = index;
14156
14157
14158
14159 if (index >= n && no_oblock)
14160 break;
14161 if (tok == '}')
14162 break;
14163 skip(',');
14164 }
14165 }
14166 if (!no_oblock)
14167 skip('}');
14168
14169 if (!size_only && n >= 0 && array_length < n) {
14170 init_putz(t1, sec, c + array_length * size1,
14171 (n - array_length) * size1);
14172 }
14173
14174 if (n < 0)
14175 s->c = array_length;
14176 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
14177 (sec || !first || tok == '{')) {
14178 int par_count;
14179
14180
14181
14182
14183
14184
14185
14186
14187
14188 = 0;
14189 if (tok == '(') {
14190 AttributeDef ad1;
14191 CType type1;
14192 next();
14193 while (tok == '(') {
14194 par_count++;
14195 next();
14196 }
14197 if (!parse_btype(&type1, &ad1))
14198 expect("cast");
14199 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
14200 #if 0
14201 if (!is_assignable_types(type, &type1))
14202 error("invalid type for cast");
14203 #endif
14204 skip(')');
14205 }
14206 no_oblock = 1;
14207 if (first || tok == '{') {
14208 skip('{');
14209 no_oblock = 0;
14210 }
14211 s = type->ref;
14212 f = s->next;
14213 array_length = 0;
14214 index = 0;
14215 n = s->c;
14216 while (tok != '}') {
14217 decl_designator(type, sec, c, NULL, &f, size_only);
14218 index = f->c;
14219 if (!size_only && array_length < index) {
14220 init_putz(type, sec, c + array_length,
14221 index - array_length);
14222 }
14223 index = index + type_size(&f->type, &align1);
14224 if (index > array_length)
14225 array_length = index;
14226 f = f->next;
14227 if (no_oblock && f == NULL)
14228 break;
14229 if (tok == '}')
14230 break;
14231 skip(',');
14232 }
14233
14234 if (!size_only && array_length < n) {
14235 init_putz(type, sec, c + array_length,
14236 n - array_length);
14237 }
14238 if (!no_oblock)
14239 skip('}');
14240 while (par_count) {
14241 skip(')');
14242 par_count--;
14243 }
14244 } else if (tok == '{') {
14245 next();
14246 decl_initializer(type, sec, c, first, size_only);
14247 skip('}');
14248 } else if (size_only) {
14249
14250 = 0;
14251 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
14252 tok != -1) {
14253 if (tok == '(')
14254 parlevel++;
14255 else if (tok == ')')
14256 parlevel--;
14257 next();
14258 }
14259 } else {
14260
14261
14262 = EXPR_CONST;
14263 if (!sec)
14264 expr_type = EXPR_ANY;
14265 init_putv(type, sec, c, 0, expr_type);
14266 }
14267 }
14268
14269
14270
14271
14272
14273
14274
14275
14276 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
14277 int has_init, int v, int scope)
14278 {
14279 int size, align, addr, data_offset;
14280 int level;
14281 ParseState saved_parse_state;
14282 TokenString init_str;
14283 Section *sec;
14284
14285 size = type_size(type, &align);
14286
14287
14288
14289
14290
14291
14292 (&init_str);
14293 if (size < 0) {
14294 if (!has_init)
14295 error("unknown type size");
14296
14297 if (has_init == 2) {
14298
14299 while (tok == TOK_STR || tok == TOK_LSTR) {
14300 tok_str_add_tok(&init_str);
14301 next();
14302 }
14303 } else {
14304 level = 0;
14305 while (level > 0 || (tok != ',' && tok != ';')) {
14306 if (tok < 0)
14307 error("unexpected end of file in initializer");
14308 tok_str_add_tok(&init_str);
14309 if (tok == '{')
14310 level++;
14311 else if (tok == '}') {
14312 if (level == 0)
14313 break;
14314 level--;
14315 }
14316 next();
14317 }
14318 }
14319 tok_str_add(&init_str, -1);
14320 tok_str_add(&init_str, 0);
14321
14322
14323 (&saved_parse_state);
14324
14325 macro_ptr = init_str.str;
14326 next();
14327 decl_initializer(type, NULL, 0, 1, 1);
14328
14329 = init_str.str;
14330 next();
14331
14332
14333 = type_size(type, &align);
14334 if (size < 0)
14335 error("unknown type size");
14336 }
14337
14338 if (ad->aligned) {
14339 if (ad->aligned > align)
14340 align = ad->aligned;
14341 } else if (ad->packed) {
14342 align = 1;
14343 }
14344 if ((r & VT_VALMASK) == VT_LOCAL) {
14345 sec = NULL;
14346 if (do_bounds_check && (type->t & VT_ARRAY))
14347 loc--;
14348 loc = (loc - size) & -align;
14349 addr = loc;
14350
14351
14352
14353 if (do_bounds_check && (type->t & VT_ARRAY)) {
14354 unsigned long *bounds_ptr;
14355
14356 --;
14357
14358 = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
14359 bounds_ptr[0] = addr;
14360 bounds_ptr[1] = size;
14361 }
14362 if (v) {
14363
14364 (v, type, r, addr);
14365 } else {
14366
14367 (type, r, addr);
14368 }
14369 } else {
14370 Sym *sym;
14371
14372 sym = NULL;
14373 if (v && scope == VT_CONST) {
14374
14375 = sym_find(v);
14376 if (sym) {
14377 if (!is_compatible_types(&sym->type, type))
14378 error("incompatible types for redefinition of '%s'",
14379 get_tok_str(v, NULL));
14380 if (sym->type.t & VT_EXTERN) {
14381
14382 ->type.t &= ~VT_EXTERN;
14383
14384
14385 if ((sym->type.t & VT_ARRAY) &&
14386 sym->type.ref->c < 0 &&
14387 type->ref->c >= 0)
14388 sym->type.ref->c = type->ref->c;
14389 } else {
14390
14391
14392
14393
14394
14395
14396
14397 if (!has_init)
14398 goto no_alloc;
14399 }
14400 }
14401 }
14402
14403
14404 = ad->section;
14405 if (!sec) {
14406 if (has_init)
14407 sec = data_section;
14408 else if (tcc_state->nocommon)
14409 sec = bss_section;
14410 }
14411 if (sec) {
14412 data_offset = sec->data_offset;
14413 data_offset = (data_offset + align - 1) & -align;
14414 addr = data_offset;
14415
14416
14417 += size;
14418
14419 if (do_bounds_check)
14420 data_offset++;
14421 sec->data_offset = data_offset;
14422
14423 if (sec->sh_type != SHT_NOBITS &&
14424 data_offset > sec->data_allocated)
14425 section_realloc(sec, data_offset);
14426
14427 if (align > sec->sh_addralign)
14428 sec->sh_addralign = align;
14429 } else {
14430 addr = 0;
14431 }
14432
14433 if (v) {
14434 if (scope == VT_CONST) {
14435 if (!sym)
14436 goto do_def;
14437 } else {
14438 do_def:
14439 sym = sym_push(v, type, r | VT_SYM, 0);
14440 }
14441
14442 if (sec) {
14443 put_extern_sym(sym, sec, addr, size);
14444 } else {
14445 Elf32_Sym *esym;
14446
14447 (sym, NULL, align, size);
14448
14449 = &((Elf32_Sym *)symtab_section->data)[sym->c];
14450 esym->st_shndx = SHN_COMMON;
14451 }
14452 } else {
14453 CValue cval;
14454
14455
14456 = get_sym_ref(type, sec, addr, size);
14457 cval.ul = 0;
14458 vsetc(type, VT_CONST | VT_SYM, &cval);
14459 vtop->sym = sym;
14460 }
14461
14462
14463
14464 if (do_bounds_check) {
14465 unsigned long *bounds_ptr;
14466
14467 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32);
14468
14469 = section_ptr_add(bounds_section, 2 * sizeof(long));
14470 bounds_ptr[0] = 0;
14471 [1] = size;
14472 }
14473 }
14474 if (has_init) {
14475 decl_initializer(type, sec, addr, 1, 0);
14476
14477 if (init_str.str) {
14478 tok_str_free(init_str.str);
14479 restore_parse_state(&saved_parse_state);
14480 }
14481 }
14482 no_alloc: ;
14483 }
14484
14485 void put_func_debug(Sym *sym)
14486 {
14487 char buf[512];
14488
14489
14490
14491 (buf, sizeof(buf), "%s:%c1",
14492 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
14493 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
14494 cur_text_section, sym->c);
14495 last_ind = 0;
14496 last_line_num = 0;
14497 }
14498
14499
14500
14501 static void func_decl_list(Sym *func_sym)
14502 {
14503 AttributeDef ad;
14504 int v;
14505 Sym *s;
14506 CType btype, type;
14507
14508
14509 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) {
14510 if (!parse_btype(&btype, &ad))
14511 expect("declaration list");
14512 if (((btype.t & VT_BTYPE) == VT_ENUM ||
14513 (btype.t & VT_BTYPE) == VT_STRUCT) &&
14514 tok == ';') {
14515
14516 } else {
14517 for(;;) {
14518 type = btype;
14519 type_decl(&type, &ad, &v, TYPE_DIRECT);
14520
14521 = func_sym->next;
14522 while (s != NULL) {
14523 if ((s->v & ~SYM_FIELD) == v)
14524 goto found;
14525 s = s->next;
14526 }
14527 error("declaration for parameter '%s' but no such parameter",
14528 get_tok_str(v, NULL));
14529 found:
14530
14531 if (type.t & VT_STORAGE)
14532 error("storage class specified for '%s'", get_tok_str(v, NULL));
14533 convert_parameter_type(&type);
14534
14535 ->type = type;
14536
14537 if (tok == ',')
14538 next();
14539 else
14540 break;
14541 }
14542 }
14543 skip(';');
14544 }
14545 }
14546
14547
14548
14549 static void gen_function(Sym *sym)
14550 {
14551 ind = cur_text_section->data_offset;
14552
14553 (sym, cur_text_section, ind, 0);
14554 funcname = get_tok_str(sym->v, NULL);
14555 func_ind = ind;
14556
14557 if (do_debug)
14558 put_func_debug(sym);
14559
14560 (&local_stack, SYM_FIELD, 0, 0);
14561 gfunc_prolog(&sym->type);
14562 rsym = 0;
14563 block(NULL, NULL, NULL, NULL, 0, 0);
14564 gsym(rsym);
14565 gfunc_epilog();
14566 cur_text_section->data_offset = ind;
14567 label_pop(&global_label_stack, NULL);
14568 sym_pop(&local_stack, NULL);
14569
14570
14571 ((Elf32_Sym *)symtab_section->data)[sym->c].st_size =
14572 ind - func_ind;
14573 if (do_debug) {
14574 put_stabn(N_FUN, 0, 0, ind - func_ind);
14575 }
14576 funcname = "";
14577 .t = VT_VOID;
14578 = 0;
14579 }
14580
14581 static void gen_inline_functions(void)
14582 {
14583 Sym *sym;
14584 CType *type;
14585 int *str, inline_generated;
14586
14587
14588 for(;;) {
14589 inline_generated = 0;
14590 for(sym = global_stack; sym != NULL; sym = sym->prev) {
14591 type = &sym->type;
14592 if (((type->t & VT_BTYPE) == VT_FUNC) &&
14593 (type->t & (VT_STATIC | VT_INLINE)) ==
14594 (VT_STATIC | VT_INLINE) &&
14595 sym->c != 0) {
14596
14597
14598 = (int *)sym->r;
14599 sym->r = VT_SYM | VT_CONST;
14600 type->t &= ~VT_INLINE;
14601
14602 macro_ptr = str;
14603 next();
14604 cur_text_section = text_section;
14605 gen_function(sym);
14606 macro_ptr = NULL;
14607
14608 (str);
14609 inline_generated = 1;
14610 }
14611 }
14612 if (!inline_generated)
14613 break;
14614 }
14615
14616
14617 for(sym = global_stack; sym != NULL; sym = sym->prev) {
14618 type = &sym->type;
14619 if (((type->t & VT_BTYPE) == VT_FUNC) &&
14620 (type->t & (VT_STATIC | VT_INLINE)) ==
14621 (VT_STATIC | VT_INLINE)) {
14622 str = (int *)sym->r;
14623 tok_str_free(str);
14624 sym->r = 0;
14625 }
14626 }
14627 }
14628
14629
14630 static void decl(int l)
14631 {
14632 int v, has_init, r;
14633 CType type, btype;
14634 Sym *sym;
14635 AttributeDef ad;
14636
14637 while (1) {
14638 if (!parse_btype(&btype, &ad)) {
14639
14640
14641 if (tok == ';') {
14642 next();
14643 continue;
14644 }
14645 if (l == VT_CONST &&
14646 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
14647
14648 ();
14649 continue;
14650 }
14651
14652
14653 if (l == VT_LOCAL || tok < TOK_DEFINE)
14654 break;
14655 btype.t = VT_INT;
14656 }
14657 if (((btype.t & VT_BTYPE) == VT_ENUM ||
14658 (btype.t & VT_BTYPE) == VT_STRUCT) &&
14659 tok == ';') {
14660
14661 ();
14662 continue;
14663 }
14664 while (1) {
14665 = btype;
14666 type_decl(&type, &ad, &v, TYPE_DIRECT);
14667 #if 0
14668 {
14669 char buf[500];
14670 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
14671 printf("type = '%s'\n", buf);
14672 }
14673 #endif
14674 if ((type.t & VT_BTYPE) == VT_FUNC) {
14675
14676
14677 = type.ref;
14678 if (sym->c == FUNC_OLD)
14679 func_decl_list(sym);
14680 }
14681
14682 if (tok == '{') {
14683 if (l == VT_LOCAL)
14684 error("cannot use local functions");
14685 if (!(type.t & VT_FUNC))
14686 expect("function definition");
14687
14688
14689 = type.ref;
14690 while ((sym = sym->next) != NULL)
14691 if (!(sym->v & ~SYM_FIELD))
14692 expect("identifier");
14693
14694
14695 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
14696 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
14697
14698 sym = sym_find(v);
14699 if (sym) {
14700 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
14701 goto func_error1;
14702
14703
14704
14705 if (sym->type.ref->r != FUNC_CDECL &&
14706 type.ref->r == FUNC_CDECL)
14707 type.ref->r = sym->type.ref->r;
14708 if (!is_compatible_types(&sym->type, &type)) {
14709 func_error1:
14710 error("incompatible types for redefinition of '%s'",
14711 get_tok_str(v, NULL));
14712 }
14713
14714 ->type = type;
14715 } else {
14716
14717 = global_identifier_push(v, type.t, 0);
14718 sym->type.ref = type.ref;
14719 }
14720
14721
14722
14723
14724 if ((type.t & (VT_INLINE | VT_STATIC)) ==
14725 (VT_INLINE | VT_STATIC)) {
14726 TokenString func_str;
14727 int block_level;
14728
14729 tok_str_new(&func_str);
14730
14731 block_level = 0;
14732 for(;;) {
14733 int t;
14734 if (tok == TOK_EOF)
14735 error("unexpected end of file");
14736 tok_str_add_tok(&func_str);
14737 t = tok;
14738 next();
14739 if (t == '{') {
14740 block_level++;
14741 } else if (t == '}') {
14742 block_level--;
14743 if (block_level == 0)
14744 break;
14745 }
14746 }
14747 tok_str_add(&func_str, -1);
14748 tok_str_add(&func_str, 0);
14749 sym->r = (long)func_str.str;
14750 } else {
14751
14752 = ad.section;
14753 if (!cur_text_section)
14754 cur_text_section = text_section;
14755 sym->r = VT_SYM | VT_CONST;
14756 gen_function(sym);
14757 #ifdef TCC_TARGET_PE
14758 if (ad.dllexport) {
14759 ((Elf32_Sym *)symtab_section->data)[sym->c].st_other |= 1;
14760 }
14761 #endif
14762 }
14763 break;
14764 } else {
14765 if (btype.t & VT_TYPEDEF) {
14766
14767
14768 = sym_push(v, &type, 0, 0);
14769 sym->type.t |= VT_TYPEDEF;
14770 } else if ((type.t & VT_BTYPE) == VT_FUNC) {
14771
14772
14773 if (ad.func_call)
14774 type.ref->r = ad.func_call;
14775 external_sym(v, &type, 0);
14776 } else {
14777
14778 = 0;
14779 if (!(type.t & VT_ARRAY))
14780 r |= lvalue_type(type.t);
14781 has_init = (tok == '=');
14782 if ((btype.t & VT_EXTERN) ||
14783 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
14784 !has_init && l == VT_CONST && type.ref->c < 0)) {
14785
14786
14787
14788
14789 (v, &type, r);
14790 } else {
14791 if (type.t & VT_STATIC)
14792 r |= VT_CONST;
14793 else
14794 r |= l;
14795 if (has_init)
14796 next();
14797 decl_initializer_alloc(&type, &ad, r,
14798 has_init, v, l);
14799 }
14800 }
14801 if (tok != ',') {
14802 skip(';');
14803 break;
14804 }
14805 next();
14806 }
14807 }
14808 }
14809 }
14810
14811
14812
14813 static void preprocess_init(TCCState *s1)
14814 {
14815 s1->include_stack_ptr = s1->include_stack;
14816
14817
14818 ->ifdef_stack_ptr = s1->ifdef_stack;
14819 file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
14820
14821
14822 = vstack - 1;
14823 s1->pack_stack[0] = 0;
14824 s1->pack_stack_ptr = s1->pack_stack;
14825 }
14826
14827
14828 static int tcc_compile(TCCState *s1)
14829 {
14830 Sym *define_start;
14831 char buf[512];
14832 volatile int section_sym;
14833
14834 #ifdef INC_DEBUG
14835 printf("%s: **** new file\n", file->filename);
14836 #endif
14837 preprocess_init(s1);
14838
14839 funcname = "";
14840 anon_sym = SYM_FIRST_ANOM;
14841
14842
14843 = 0;
14844 if (do_debug) {
14845 section_sym = put_elf_sym(symtab_section, 0, 0,
14846 ELF32_ST_INFO(STB_LOCAL, STT_SECTION), 0,
14847 text_section->sh_num, NULL);
14848 dummy_char_star = getcwd(buf, sizeof(buf));
14849 pstrcat(buf, sizeof(buf), "/");
14850 put_stabs_r(buf, N_SO, 0, 0,
14851 text_section->data_offset, text_section, section_sym);
14852 put_stabs_r(file->filename, N_SO, 0, 0,
14853 text_section->data_offset, text_section, section_sym);
14854 }
14855
14856
14857 (symtab_section, 0, 0,
14858 ELF32_ST_INFO(STB_LOCAL, STT_FILE), 0,
14859 SHN_ABS, file->filename);
14860
14861
14862 .t = VT_INT;
14863
14864 char_pointer_type.t = VT_BYTE;
14865 mk_pointer(&char_pointer_type);
14866
14867 func_old_type.t = VT_FUNC;
14868 func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);
14869
14870 #if 0
14871
14872 {
14873 Sym *s1;
14874
14875 p = anon_sym++;
14876 sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW);
14877 s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0);
14878 s1->next = NULL;
14879 sym->next = s1;
14880 sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0);
14881 }
14882 #endif
14883
14884 define_start = define_stack;
14885
14886 if (setjmp(s1->error_jmp_buf) == 0) {
14887 s1->nb_errors = 0;
14888 s1->error_set_jmp_enabled = 1;
14889
14890 ch = file->buf_ptr[0];
14891 tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
14892 parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM;
14893 next();
14894 decl(VT_CONST);
14895 if (tok != TOK_EOF)
14896 expect("declaration");
14897
14898
14899 if (do_debug) {
14900 put_stabs_r(NULL, N_SO, 0, 0,
14901 text_section->data_offset, text_section, section_sym);
14902 }
14903 }
14904 s1->error_set_jmp_enabled = 0;
14905
14906
14907
14908 (define_start);
14909
14910 gen_inline_functions();
14911
14912 sym_pop(&global_stack, NULL);
14913
14914 return s1->nb_errors != 0 ? -1 : 0;
14915 }
14916
14917 #ifdef LIBTCC
14918 int tcc_compile_string(TCCState *s, const char *str)
14919 {
14920 BufferedFile bf1, *bf = &bf1;
14921 int ret, len;
14922 char *buf;
14923
14924
14925 bf->fd = -1;
14926
14927 len = strlen(str);
14928 buf = tcc_malloc(len + 1);
14929 if (!buf)
14930 return -1;
14931 memcpy(buf, str, len);
14932 buf[len] = CH_EOB;
14933 bf->buf_ptr = buf;
14934 bf->buf_end = buf + len;
14935 pstrcpy(bf->filename, sizeof(bf->filename), "<string>");
14936 bf->line_num = 1;
14937 file = bf;
14938
14939 ret = tcc_compile(s);
14940
14941 tcc_free(buf);
14942
14943
14944 return ret;
14945 }
14946 #endif
14947
14948
14949 void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
14950 {
14951 BufferedFile bf1, *bf = &bf1;
14952
14953 pstrcpy(bf->buffer, IO_BUF_SIZE, sym);
14954 pstrcat(bf->buffer, IO_BUF_SIZE, " ");
14955
14956 if (!value)
14957 value = "1";
14958 pstrcat(bf->buffer, IO_BUF_SIZE, value);
14959
14960
14961 ->fd = -1;
14962 bf->buf_ptr = bf->buffer;
14963 bf->buf_end = bf->buffer + strlen(bf->buffer);
14964 *bf->buf_end = CH_EOB;
14965 bf->filename[0] = '\0';
14966 bf->line_num = 1;
14967 file = bf;
14968
14969 s1->include_stack_ptr = s1->include_stack;
14970
14971
14972 = file->buf_ptr[0];
14973 next_nomacro();
14974 parse_define();
14975 file = NULL;
14976 }
14977
14978
14979 void tcc_undefine_symbol(TCCState *s1, const char *sym)
14980 {
14981 TokenSym *ts;
14982 Sym *s;
14983 ts = tok_alloc(sym, strlen(sym));
14984 s = define_find(ts->tok);
14985
14986 if (s)
14987 define_undef(s);
14988 }
14989
14990 #ifdef CONFIG_TCC_ASM
14991
14992 #ifdef TCC_TARGET_I386
14993
14994
14995
14996
14997
14998
14999
15000
15001
15002
15003
15004
15005
15006
15007
15008
15009
15010
15011
15012
15013
15014
15015
15016 #define MAX_OPERANDS 3
15017
15018 typedef struct ASMInstr {
15019 uint16_t sym;
15020 uint16_t opcode;
15021 uint16_t instr_type;
15022 #define OPC_JMP 0x01
15023 #define OPC_B 0x02
15024 #define OPC_WL 0x04
15025 #define OPC_BWL (OPC_B | OPC_WL)
15026 #define OPC_REG 0x08
15027 #define OPC_MODRM 0x10
15028 #define OPC_FWAIT 0x20
15029 #define OPC_TEST 0x40
15030 #define OPC_SHIFT 0x80
15031 #define OPC_D16 0x0100
15032 #define OPC_ARITH 0x0200
15033 #define OPC_SHORTJMP 0x0400
15034 #define OPC_FARITH 0x0800
15035 #define OPC_GROUP_SHIFT 13
15036
15037
15038
15039 #define OPT_REG8 0
15040 #define OPT_REG16 1
15041 #define OPT_REG32 2
15042 #define OPT_MMX 3
15043 #define OPT_SSE 4
15044 #define OPT_CR 5
15045 #define OPT_TR 6
15046 #define OPT_DB 7
15047 #define OPT_SEG 8
15048 #define OPT_ST 9
15049 #define OPT_IM8 10
15050 #define OPT_IM8S 11
15051 #define OPT_IM16 12
15052 #define OPT_IM32 13
15053 #define OPT_EAX 14
15054 #define OPT_ST0 15
15055 #define OPT_CL 16
15056 #define OPT_DX 17
15057 #define OPT_ADDR 18
15058 #define OPT_INDIR 19
15059
15060
15061 #define OPT_COMPOSITE_FIRST 20
15062 #define OPT_IM 20
15063 #define OPT_REG 21
15064 #define OPT_REGW 22
15065 #define OPT_IMW 23
15066
15067
15068 #define OPT_EA 0x80
15069
15070 uint8_t nb_ops;
15071 uint8_t op_type[MAX_OPERANDS];
15072 } ASMInstr;
15073
15074 typedef struct Operand {
15075 uint32_t type;
15076 #define OP_REG8 (1 << OPT_REG8)
15077 #define OP_REG16 (1 << OPT_REG16)
15078 #define OP_REG32 (1 << OPT_REG32)
15079 #define OP_MMX (1 << OPT_MMX)
15080 #define OP_SSE (1 << OPT_SSE)
15081 #define OP_CR (1 << OPT_CR)
15082 #define OP_TR (1 << OPT_TR)
15083 #define OP_DB (1 << OPT_DB)
15084 #define OP_SEG (1 << OPT_SEG)
15085 #define OP_ST (1 << OPT_ST)
15086 #define OP_IM8 (1 << OPT_IM8)
15087 #define OP_IM8S (1 << OPT_IM8S)
15088 #define OP_IM16 (1 << OPT_IM16)
15089 #define OP_IM32 (1 << OPT_IM32)
15090 #define OP_EAX (1 << OPT_EAX)
15091 #define OP_ST0 (1 << OPT_ST0)
15092 #define OP_CL (1 << OPT_CL)
15093 #define OP_DX (1 << OPT_DX)
15094 #define OP_ADDR (1 << OPT_ADDR)
15095 #define OP_INDIR (1 << OPT_INDIR)
15096
15097 #define OP_EA 0x40000000
15098 #define OP_REG (OP_REG8 | OP_REG16 | OP_REG32)
15099 #define OP_IM OP_IM32
15100 int8_t reg;
15101 ;
15102 ;
15103 ExprValue e;
15104 } Operand;
15105
15106 static const uint8_t reg_to_size[5] = {
15107 [OP_REG8] = 0,
15108 [OP_REG16] = 1,
15109 [OP_REG32] = 2,
15110 };
15111
15112 #define WORD_PREFIX_OPCODE 0x66
15113
15114 #define NB_TEST_OPCODES 30
15115
15116 static const uint8_t test_bits[NB_TEST_OPCODES] = {
15117 0x00,
15118 0x01,
15119 0x02,
15120 0x02,
15121 0x02,
15122 0x03,
15123 0x03,
15124 0x03,
15125 0x04,
15126 0x04,
15127 0x05,
15128 0x05,
15129 0x06,
15130 0x06,
15131 0x07,
15132 0x07,
15133 0x08,
15134 0x09,
15135 0x0a,
15136 0x0a,
15137 0x0b,
15138 0x0b,
15139 0x0c,
15140 0x0c,
15141 0x0d,
15142 0x0d,
15143 0x0e,
15144 0x0e,
15145 0x0f,
15146 0x0f,
15147 };
15148
15149 static const ASMInstr asm_instrs[] = {
15150 #define ALT(x) x
15151 #define DEF_ASM_OP0(name, opcode)
15152 #define DEF_ASM_OP0L(name, opcode, group, instr_type) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 0 },
15153 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 1, { op0 }},
15154 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 2, { op0, op1 }},
15155 #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 3, { op0, op1, op2 }},
15156
15157
15158
15159 (pusha, 0x60)
15160 (popa, 0x61)
15161 DEF_ASM_OP0(clc, 0xf8)
15162 DEF_ASM_OP0(cld, 0xfc)
15163 DEF_ASM_OP0(cli, 0xfa)
15164 DEF_ASM_OP0(clts, 0x0f06)
15165 DEF_ASM_OP0(cmc, 0xf5)
15166 DEF_ASM_OP0(lahf, 0x9f)
15167 DEF_ASM_OP0(sahf, 0x9e)
15168 DEF_ASM_OP0(pushfl, 0x9c)
15169 DEF_ASM_OP0(popfl, 0x9d)
15170 DEF_ASM_OP0(pushf, 0x9c)
15171 DEF_ASM_OP0(popf, 0x9d)
15172 DEF_ASM_OP0(stc, 0xf9)
15173 DEF_ASM_OP0(std, 0xfd)
15174 DEF_ASM_OP0(sti, 0xfb)
15175 DEF_ASM_OP0(aaa, 0x37)
15176 DEF_ASM_OP0(aas, 0x3f)
15177 DEF_ASM_OP0(daa, 0x27)
15178 DEF_ASM_OP0(das, 0x2f)
15179 DEF_ASM_OP0(aad, 0xd50a)
15180 DEF_ASM_OP0(aam, 0xd40a)
15181 DEF_ASM_OP0(cbw, 0x6698)
15182 DEF_ASM_OP0(cwd, 0x6699)
15183 DEF_ASM_OP0(cwde, 0x98)
15184 DEF_ASM_OP0(cdq, 0x99)
15185 DEF_ASM_OP0(cbtw, 0x6698)
15186 DEF_ASM_OP0(cwtl, 0x98)
15187 DEF_ASM_OP0(cwtd, 0x6699)
15188 DEF_ASM_OP0(cltd, 0x99)
15189 DEF_ASM_OP0(int3, 0xcc)
15190 DEF_ASM_OP0(into, 0xce)
15191 DEF_ASM_OP0(iret, 0xcf)
15192 DEF_ASM_OP0(rsm, 0x0faa)
15193 DEF_ASM_OP0(hlt, 0xf4)
15194 DEF_ASM_OP0(wait, 0x9b)
15195 DEF_ASM_OP0(nop, 0x90)
15196 DEF_ASM_OP0(xlat, 0xd7)
15197
15198
15199 (DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
15200 ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
15201
15202 ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
15203 ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
15204
15205 ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
15206 ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
15207
15208 ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
15209 ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
15210
15211 ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
15212 ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
15213
15214 ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
15215 ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
15216
15217
15218
15219 (DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
15220 ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
15221
15222 ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15223 ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15224
15225 ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15226 ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15227
15228 ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15229 ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15230
15231 ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15232 ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15233
15234
15235 (aword, 0x67)
15236 DEF_ASM_OP0(addr16, 0x67)
15237 DEF_ASM_OP0(word, 0x66)
15238 DEF_ASM_OP0(data16, 0x66)
15239 DEF_ASM_OP0(lock, 0xf0)
15240 DEF_ASM_OP0(rep, 0xf3)
15241 DEF_ASM_OP0(repe, 0xf3)
15242 DEF_ASM_OP0(repz, 0xf3)
15243 DEF_ASM_OP0(repne, 0xf2)
15244 DEF_ASM_OP0(repnz, 0xf2)
15245
15246 DEF_ASM_OP0(invd, 0x0f08)
15247 DEF_ASM_OP0(wbinvd, 0x0f09)
15248 DEF_ASM_OP0(cpuid, 0x0fa2)
15249 DEF_ASM_OP0(wrmsr, 0x0f30)
15250 DEF_ASM_OP0(rdtsc, 0x0f31)
15251 DEF_ASM_OP0(rdmsr, 0x0f32)
15252 DEF_ASM_OP0(rdpmc, 0x0f33)
15253 DEF_ASM_OP0(ud2, 0x0f0b)
15254
15255
15256 (DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
15257 ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
15258 ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
15259 ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15260 ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
15261 ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
15262
15263 ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
15264 ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
15265
15266 ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
15267 ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
15268 ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
15269 ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
15270 ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
15271 ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
15272
15273 ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
15274 ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
15275 ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
15276 ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
15277 ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
15278
15279 ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
15280 ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
15281 ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
15282 ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
15283 ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
15284
15285 ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
15286 ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
15287 ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
15288
15289 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
15290 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
15291 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
15292 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15293
15294 ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
15295 ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
15296 ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
15297 ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
15298
15299 ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
15300 ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
15301 ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
15302 ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
15303
15304 ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
15305
15306 ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15307 ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15308 ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15309 ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15310 ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15311
15312
15313 (DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
15314 (DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15315 ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
15316 ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
15317 ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
15318
15319 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15320 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
15321 ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
15322 ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
15323
15324 ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
15325 ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15326 ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
15327 ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15328
15329 ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15330 ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15331
15332 ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15333 ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15334
15335 ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
15336 ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
15337 ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
15338 ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
15339 ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
15340
15341 ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15342 ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
15343 ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15344 ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
15345
15346
15347 (DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
15348 ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
15349 ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
15350
15351 ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
15352 ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
15353 ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
15354 ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
15355 ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
15356 ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
15357
15358 ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
15359 ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
15360 ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
15361 ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
15362
15363 ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
15364 ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
15365 ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
15366 ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
15367
15368 ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
15369 ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
15370 DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
15371 DEF_ASM_OP0(leave, 0xc9)
15372 DEF_ASM_OP0(ret, 0xc3)
15373 ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
15374 DEF_ASM_OP0(lret, 0xcb)
15375 ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
15376
15377 ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
15378 DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
15379 DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
15380 DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
15381 DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
15382 DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
15383 DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
15384
15385
15386
15387 (DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
15388
15389 ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
15390 ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
15391 ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
15392 ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
15393 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
15394 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
15395 ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
15396 ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15397 ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15398 ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15399 ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15400
15401 DEF_ASM_OP0(fucompp, 0xdae9)
15402 DEF_ASM_OP0(ftst, 0xd9e4)
15403 DEF_ASM_OP0(fxam, 0xd9e5)
15404 DEF_ASM_OP0(fld1, 0xd9e8)
15405 DEF_ASM_OP0(fldl2t, 0xd9e9)
15406 DEF_ASM_OP0(fldl2e, 0xd9ea)
15407 DEF_ASM_OP0(fldpi, 0xd9eb)
15408 DEF_ASM_OP0(fldlg2, 0xd9ec)
15409 DEF_ASM_OP0(fldln2, 0xd9ed)
15410 DEF_ASM_OP0(fldz, 0xd9ee)
15411
15412 DEF_ASM_OP0(f2xm1, 0xd9f0)
15413 DEF_ASM_OP0(fyl2x, 0xd9f1)
15414 DEF_ASM_OP0(fptan, 0xd9f2)
15415 DEF_ASM_OP0(fpatan, 0xd9f3)
15416 DEF_ASM_OP0(fxtract, 0xd9f4)
15417 DEF_ASM_OP0(fprem1, 0xd9f5)
15418 DEF_ASM_OP0(fdecstp, 0xd9f6)
15419 DEF_ASM_OP0(fincstp, 0xd9f7)
15420 DEF_ASM_OP0(fprem, 0xd9f8)
15421 DEF_ASM_OP0(fyl2xp1, 0xd9f9)
15422 DEF_ASM_OP0(fsqrt, 0xd9fa)
15423 DEF_ASM_OP0(fsincos, 0xd9fb)
15424 DEF_ASM_OP0(frndint, 0xd9fc)
15425 DEF_ASM_OP0(fscale, 0xd9fd)
15426 DEF_ASM_OP0(fsin, 0xd9fe)
15427 DEF_ASM_OP0(fcos, 0xd9ff)
15428 DEF_ASM_OP0(fchs, 0xd9e0)
15429 DEF_ASM_OP0(fabs, 0xd9e1)
15430 DEF_ASM_OP0(fninit, 0xdbe3)
15431 DEF_ASM_OP0(fnclex, 0xdbe2)
15432 DEF_ASM_OP0(fnop, 0xd9d0)
15433 DEF_ASM_OP0(fwait, 0x9b)
15434
15435
15436 (fld, 0xd9c0, 0, OPC_REG, OPT_ST)
15437 DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
15438 DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
15439 ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
15440 DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
15441 DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
15442 DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
15443 DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
15444 DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
15445
15446
15447 (fst, 0xddd0, 0, OPC_REG, OPT_ST)
15448 DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
15449 DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
15450 DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
15451 ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
15452 DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
15453 DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
15454 DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
15455 DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
15456 DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
15457
15458 DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
15459 DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
15460 DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
15461 DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
15462 DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
15463
15464
15465 (fxch, 0xd9c9)
15466 ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
15467
15468
15469 (fucom, 0xdde0, 0, OPC_REG, OPT_ST )
15470 DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
15471
15472 DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
15473 DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
15474 DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
15475 DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
15476 DEF_ASM_OP0(fnstsw, 0xdfe0)
15477 ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
15478 ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
15479 DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
15480 ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
15481 ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
15482 DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
15483 DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
15484 DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
15485 DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
15486 DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
15487 DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
15488 DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
15489 DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
15490 DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
15491 DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
15492 DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
15493
15494
15495 (arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
15496 DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
15497 DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
15498 DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
15499 DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
15500 DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
15501 ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
15502 DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
15503 DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
15504 DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
15505 DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
15506 DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
15507 DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
15508 DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
15509 DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
15510
15511
15512 (bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
15513 ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
15514 ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
15515 DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
15516
15517 DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
15518 DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
15519
15520
15521 (cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
15522
15523
15524 (DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
15525
15526 DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15527 DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15528 DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15529 DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15530 DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15531 DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15532 DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15533 DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15534
15535 DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15536 DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15537 DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15538 DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15539
15540
15541 (emms, 0x0f77)
15542 (movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
15543 ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
15544 DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15545 ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
15546 DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15547 DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15548 DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15549 DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15550 DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15551 DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15552 DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15553 DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15554 DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15555 DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15556 DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15557 DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15558 DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15559 DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15560 DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15561 DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15562 DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15563 DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15564 DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15565 DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15566 DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15567 DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15568 DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15569 ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
15570 DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15571 ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
15572 DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15573 ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
15574 DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15575 ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
15576 DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15577 ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
15578 DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15579 ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
15580 DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15581 ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
15582 DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15583 ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
15584 DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15585 DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15586 DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15587 DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15588 DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15589 DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15590 DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15591 DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15592 DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15593 DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15594 DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15595 DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15596 DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15597 DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15598
15599 #undef ALT
15600 #undef DEF_ASM_OP0
15601 #undef DEF_ASM_OP0L
15602 #undef DEF_ASM_OP1
15603 #undef DEF_ASM_OP2
15604 #undef DEF_ASM_OP3
15605
15606
15607
15608 { 0, },
15609 };
15610
15611 static const uint16_t op0_codes[] = {
15612 #define ALT(x)
15613 #define DEF_ASM_OP0(x, opcode) opcode,
15614 #define DEF_ASM_OP0L(name, opcode, group, instr_type)
15615 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0)
15616 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1)
15617 #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2)
15618
15619
15620
15621 (pusha, 0x60)
15622 (popa, 0x61)
15623 DEF_ASM_OP0(clc, 0xf8)
15624 DEF_ASM_OP0(cld, 0xfc)
15625 DEF_ASM_OP0(cli, 0xfa)
15626 DEF_ASM_OP0(clts, 0x0f06)
15627 DEF_ASM_OP0(cmc, 0xf5)
15628 DEF_ASM_OP0(lahf, 0x9f)
15629 DEF_ASM_OP0(sahf, 0x9e)
15630 DEF_ASM_OP0(pushfl, 0x9c)
15631 DEF_ASM_OP0(popfl, 0x9d)
15632 DEF_ASM_OP0(pushf, 0x9c)
15633 DEF_ASM_OP0(popf, 0x9d)
15634 DEF_ASM_OP0(stc, 0xf9)
15635 DEF_ASM_OP0(std, 0xfd)
15636 DEF_ASM_OP0(sti, 0xfb)
15637 DEF_ASM_OP0(aaa, 0x37)
15638 DEF_ASM_OP0(aas, 0x3f)
15639 DEF_ASM_OP0(daa, 0x27)
15640 DEF_ASM_OP0(das, 0x2f)
15641 DEF_ASM_OP0(aad, 0xd50a)
15642 DEF_ASM_OP0(aam, 0xd40a)
15643 DEF_ASM_OP0(cbw, 0x6698)
15644 DEF_ASM_OP0(cwd, 0x6699)
15645 DEF_ASM_OP0(cwde, 0x98)
15646 DEF_ASM_OP0(cdq, 0x99)
15647 DEF_ASM_OP0(cbtw, 0x6698)
15648 DEF_ASM_OP0(cwtl, 0x98)
15649 DEF_ASM_OP0(cwtd, 0x6699)
15650 DEF_ASM_OP0(cltd, 0x99)
15651 DEF_ASM_OP0(int3, 0xcc)
15652 DEF_ASM_OP0(into, 0xce)
15653 DEF_ASM_OP0(iret, 0xcf)
15654 DEF_ASM_OP0(rsm, 0x0faa)
15655 DEF_ASM_OP0(hlt, 0xf4)
15656 DEF_ASM_OP0(wait, 0x9b)
15657 DEF_ASM_OP0(nop, 0x90)
15658 DEF_ASM_OP0(xlat, 0xd7)
15659
15660
15661 (DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
15662 ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
15663
15664 ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
15665 ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
15666
15667 ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
15668 ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
15669
15670 ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
15671 ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
15672
15673 ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
15674 ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
15675
15676 ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
15677 ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
15678
15679
15680
15681 (DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
15682 ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
15683
15684 ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15685 ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15686
15687 ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15688 ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15689
15690 ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15691 ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15692
15693 ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15694 ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15695
15696
15697 (aword, 0x67)
15698 DEF_ASM_OP0(addr16, 0x67)
15699 DEF_ASM_OP0(word, 0x66)
15700 DEF_ASM_OP0(data16, 0x66)
15701 DEF_ASM_OP0(lock, 0xf0)
15702 DEF_ASM_OP0(rep, 0xf3)
15703 DEF_ASM_OP0(repe, 0xf3)
15704 DEF_ASM_OP0(repz, 0xf3)
15705 DEF_ASM_OP0(repne, 0xf2)
15706 DEF_ASM_OP0(repnz, 0xf2)
15707
15708 DEF_ASM_OP0(invd, 0x0f08)
15709 DEF_ASM_OP0(wbinvd, 0x0f09)
15710 DEF_ASM_OP0(cpuid, 0x0fa2)
15711 DEF_ASM_OP0(wrmsr, 0x0f30)
15712 DEF_ASM_OP0(rdtsc, 0x0f31)
15713 DEF_ASM_OP0(rdmsr, 0x0f32)
15714 DEF_ASM_OP0(rdpmc, 0x0f33)
15715 DEF_ASM_OP0(ud2, 0x0f0b)
15716
15717
15718 (DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
15719 ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
15720 ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
15721 ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15722 ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
15723 ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
15724
15725 ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
15726 ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
15727
15728 ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
15729 ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
15730 ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
15731 ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
15732 ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
15733 ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
15734
15735 ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
15736 ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
15737 ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
15738 ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
15739 ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
15740
15741 ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
15742 ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
15743 ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
15744 ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
15745 ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
15746
15747 ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
15748 ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
15749 ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
15750
15751 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
15752 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
15753 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
15754 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15755
15756 ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
15757 ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
15758 ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
15759 ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
15760
15761 ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
15762 ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
15763 ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
15764 ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
15765
15766 ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
15767
15768 ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15769 ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15770 ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15771 ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15772 ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15773
15774
15775 (DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
15776 (DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15777 ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
15778 ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
15779 ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
15780
15781 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15782 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
15783 ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
15784 ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
15785
15786 ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
15787 ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15788 ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
15789 ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15790
15791 ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15792 ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15793
15794 ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15795 ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15796
15797 ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
15798 ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
15799 ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
15800 ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
15801 ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
15802
15803 ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15804 ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
15805 ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15806 ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
15807
15808
15809 (DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
15810 ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
15811 ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
15812
15813 ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
15814 ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
15815 ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
15816 ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
15817 ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
15818 ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
15819
15820 ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
15821 ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
15822 ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
15823 ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
15824
15825 ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
15826 ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
15827 ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
15828 ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
15829
15830 ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
15831 ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
15832 DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
15833 DEF_ASM_OP0(leave, 0xc9)
15834 DEF_ASM_OP0(ret, 0xc3)
15835 ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
15836 DEF_ASM_OP0(lret, 0xcb)
15837 ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
15838
15839 ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
15840 DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
15841 DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
15842 DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
15843 DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
15844 DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
15845 DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
15846
15847
15848
15849 (DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
15850
15851 ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
15852 ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
15853 ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
15854 ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
15855 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
15856 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
15857 ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
15858 ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15859 ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15860 ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15861 ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15862
15863 DEF_ASM_OP0(fucompp, 0xdae9)
15864 DEF_ASM_OP0(ftst, 0xd9e4)
15865 DEF_ASM_OP0(fxam, 0xd9e5)
15866 DEF_ASM_OP0(fld1, 0xd9e8)
15867 DEF_ASM_OP0(fldl2t, 0xd9e9)
15868 DEF_ASM_OP0(fldl2e, 0xd9ea)
15869 DEF_ASM_OP0(fldpi, 0xd9eb)
15870 DEF_ASM_OP0(fldlg2, 0xd9ec)
15871 DEF_ASM_OP0(fldln2, 0xd9ed)
15872 DEF_ASM_OP0(fldz, 0xd9ee)
15873
15874 DEF_ASM_OP0(f2xm1, 0xd9f0)
15875 DEF_ASM_OP0(fyl2x, 0xd9f1)
15876 DEF_ASM_OP0(fptan, 0xd9f2)
15877 DEF_ASM_OP0(fpatan, 0xd9f3)
15878 DEF_ASM_OP0(fxtract, 0xd9f4)
15879 DEF_ASM_OP0(fprem1, 0xd9f5)
15880 DEF_ASM_OP0(fdecstp, 0xd9f6)
15881 DEF_ASM_OP0(fincstp, 0xd9f7)
15882 DEF_ASM_OP0(fprem, 0xd9f8)
15883 DEF_ASM_OP0(fyl2xp1, 0xd9f9)
15884 DEF_ASM_OP0(fsqrt, 0xd9fa)
15885 DEF_ASM_OP0(fsincos, 0xd9fb)
15886 DEF_ASM_OP0(frndint, 0xd9fc)
15887 DEF_ASM_OP0(fscale, 0xd9fd)
15888 DEF_ASM_OP0(fsin, 0xd9fe)
15889 DEF_ASM_OP0(fcos, 0xd9ff)
15890 DEF_ASM_OP0(fchs, 0xd9e0)
15891 DEF_ASM_OP0(fabs, 0xd9e1)
15892 DEF_ASM_OP0(fninit, 0xdbe3)
15893 DEF_ASM_OP0(fnclex, 0xdbe2)
15894 DEF_ASM_OP0(fnop, 0xd9d0)
15895 DEF_ASM_OP0(fwait, 0x9b)
15896
15897
15898 (fld, 0xd9c0, 0, OPC_REG, OPT_ST)
15899 DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
15900 DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
15901 ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
15902 DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
15903 DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
15904 DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
15905 DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
15906 DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
15907
15908
15909 (fst, 0xddd0, 0, OPC_REG, OPT_ST)
15910 DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
15911 DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
15912 DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
15913 ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
15914 DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
15915 DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
15916 DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
15917 DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
15918 DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
15919
15920 DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
15921 DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
15922 DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
15923 DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
15924 DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
15925
15926
15927 (fxch, 0xd9c9)
15928 ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
15929
15930
15931 (fucom, 0xdde0, 0, OPC_REG, OPT_ST )
15932 DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
15933
15934 DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
15935 DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
15936 DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
15937 DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
15938 DEF_ASM_OP0(fnstsw, 0xdfe0)
15939 ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
15940 ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
15941 DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
15942 ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
15943 ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
15944 DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
15945 DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
15946 DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
15947 DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
15948 DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
15949 DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
15950 DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
15951 DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
15952 DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
15953 DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
15954 DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
15955
15956
15957 (arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
15958 DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
15959 DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
15960 DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
15961 DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
15962 DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
15963 ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
15964 DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
15965 DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
15966 DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
15967 DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
15968 DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
15969 DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
15970 DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
15971 DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
15972
15973
15974 (bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
15975 ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
15976 ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
15977 DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
15978
15979 DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
15980 DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
15981
15982
15983 (cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
15984
15985
15986 (DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
15987
15988 DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15989 DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15990 DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15991 DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15992 DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15993 DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15994 DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15995 DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15996
15997 DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15998 DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15999 DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
16000 DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
16001
16002
16003 (emms, 0x0f77)
16004 (movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
16005 ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
16006 DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16007 ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
16008 DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16009 DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16010 DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16011 DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16012 DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16013 DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16014 DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16015 DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16016 DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16017 DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16018 DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16019 DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16020 DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16021 DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16022 DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16023 DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16024 DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16025 DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16026 DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16027 DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16028 DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16029 DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16030 DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16031 ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
16032 DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16033 ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
16034 DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16035 ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
16036 DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16037 ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
16038 DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16039 ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
16040 DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16041 ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
16042 DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16043 ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
16044 DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16045 ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
16046 DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16047 DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16048 DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16049 DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16050 DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16051 DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16052 DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16053 DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16054 DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16055 DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16056 DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16057 DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16058 DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16059 DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16060
16061 #undef ALT
16062 #undef DEF_ASM_OP0
16063 #undef DEF_ASM_OP0L
16064 #undef DEF_ASM_OP1
16065 #undef DEF_ASM_OP2
16066 #undef DEF_ASM_OP3
16067
16068 };
16069
16070 static inline int get_reg_shift(TCCState *s1)
16071 {
16072 int shift, v;
16073
16074 v = asm_int_expr(s1);
16075 switch(v) {
16076 case 1:
16077 shift = 0;
16078 break;
16079 case 2:
16080 shift = 1;
16081 break;
16082 case 4:
16083 shift = 2;
16084 break;
16085 case 8:
16086 shift = 3;
16087 break;
16088 default:
16089 expect("1, 2, 4 or 8 constant");
16090 shift = 0;
16091 break;
16092 }
16093 return shift;
16094 }
16095
16096 static int asm_parse_reg(void)
16097 {
16098 int reg;
16099 if (tok != '%')
16100 goto error_32;
16101 next();
16102 if (tok >= TOK_ASM_eax && tok <= TOK_ASM_edi) {
16103 reg = tok - TOK_ASM_eax;
16104 next();
16105 return reg;
16106 } else {
16107 error_32:
16108 expect("32 bit register");
16109 return 0;
16110 }
16111 }
16112
16113 static void parse_operand(TCCState *s1, Operand *op)
16114 {
16115 ExprValue e;
16116 int reg, indir;
16117 const char *p;
16118
16119 indir = 0;
16120 if (tok == '*') {
16121 next();
16122 indir = OP_INDIR;
16123 }
16124
16125 if (tok == '%') {
16126 next();
16127 if (tok >= TOK_ASM_al && tok <= TOK_ASM_db7) {
16128 reg = tok - TOK_ASM_al;
16129 op->type = 1 << (reg >> 3);
16130 ->reg = reg & 7;
16131 if ((op->type & OP_REG) && op->reg == TREG_EAX)
16132 op->type |= OP_EAX;
16133 else if (op->type == OP_REG8 && op->reg == TREG_ECX)
16134 op->type |= OP_CL;
16135 else if (op->type == OP_REG16 && op->reg == TREG_EDX)
16136 op->type |= OP_DX;
16137 } else if (tok >= TOK_ASM_dr0 && tok <= TOK_ASM_dr7) {
16138 op->type = OP_DB;
16139 op->reg = tok - TOK_ASM_dr0;
16140 } else if (tok >= TOK_ASM_es && tok <= TOK_ASM_gs) {
16141 op->type = OP_SEG;
16142 op->reg = tok - TOK_ASM_es;
16143 } else if (tok == TOK_ASM_st) {
16144 op->type = OP_ST;
16145 op->reg = 0;
16146 next();
16147 if (tok == '(') {
16148 next();
16149 if (tok != TOK_PPNUM)
16150 goto reg_error;
16151 p = tokc.cstr->data;
16152 reg = p[0] - '0';
16153 if ((unsigned)reg >= 8 || p[1] != '\0')
16154 goto reg_error;
16155 op->reg = reg;
16156 next();
16157 skip(')');
16158 }
16159 if (op->reg == 0)
16160 op->type |= OP_ST0;
16161 goto no_skip;
16162 } else {
16163 reg_error:
16164 error("unknown register");
16165 }
16166 next();
16167 no_skip: ;
16168 } else if (tok == '$') {
16169
16170 ();
16171 asm_expr(s1, &e);
16172 op->type = OP_IM32;
16173 op->e.v = e.v;
16174 op->e.sym = e.sym;
16175 if (!op->e.sym) {
16176 if (op->e.v == (uint8_t)op->e.v)
16177 op->type |= OP_IM8;
16178 if (op->e.v == (int8_t)op->e.v)
16179 op->type |= OP_IM8S;
16180 if (op->e.v == (uint16_t)op->e.v)
16181 op->type |= OP_IM16;
16182 }
16183 } else {
16184
16185 ->type = OP_EA;
16186 op->reg = -1;
16187 op->reg2 = -1;
16188 op->shift = 0;
16189 if (tok != '(') {
16190 asm_expr(s1, &e);
16191 op->e.v = e.v;
16192 op->e.sym = e.sym;
16193 } else {
16194 op->e.v = 0;
16195 op->e.sym = NULL;
16196 }
16197 if (tok == '(') {
16198 next();
16199 if (tok != ',') {
16200 op->reg = asm_parse_reg();
16201 }
16202 if (tok == ',') {
16203 next();
16204 if (tok != ',') {
16205 op->reg2 = asm_parse_reg();
16206 }
16207 skip(',');
16208 op->shift = get_reg_shift(s1);
16209 }
16210 skip(')');
16211 }
16212 if (op->reg == -1 && op->reg2 == -1)
16213 op->type |= OP_ADDR;
16214 }
16215 op->type |= indir;
16216 }
16217
16218
16219 static void gen_expr32(ExprValue *pe)
16220 {
16221 if (pe->sym)
16222 greloc(cur_text_section, pe->sym, ind, R_386_32);
16223 gen_le32(pe->v);
16224 }
16225
16226
16227 static void gen_disp32(ExprValue *pe)
16228 {
16229 Sym *sym;
16230 sym = pe->sym;
16231 if (sym) {
16232 if (sym->r == cur_text_section->sh_num) {
16233
16234
16235
16236
16237 (pe->v + (long)sym->next - ind - 4);
16238 } else {
16239 greloc(cur_text_section, sym, ind, R_386_PC32);
16240 gen_le32(pe->v - 4);
16241 }
16242 } else {
16243
16244 (symtab_section, cur_text_section,
16245 ind, R_386_PC32, 0);
16246 gen_le32(pe->v - 4);
16247 }
16248 }
16249
16250
16251 static void gen_le16(int v)
16252 {
16253 g(v);
16254 g(v >> 8);
16255 }
16256
16257
16258 static inline void asm_modrm(int reg, Operand *op)
16259 {
16260 int mod, reg1, reg2, sib_reg1;
16261
16262 if (op->type & (OP_REG | OP_MMX | OP_SSE)) {
16263 g(0xc0 + (reg << 3) + op->reg);
16264 } else if (op->reg == -1 && op->reg2 == -1) {
16265
16266 (0x05 + (reg << 3));
16267 gen_expr32(&op->e);
16268 } else {
16269 sib_reg1 = op->reg;
16270
16271 if (sib_reg1 == -1) {
16272 sib_reg1 = 5;
16273 mod = 0x00;
16274 } else if (op->e.v == 0 && !op->e.sym && op->reg != 5) {
16275 mod = 0x00;
16276 } else if (op->e.v == (int8_t)op->e.v && !op->e.sym) {
16277 mod = 0x40;
16278 } else {
16279 mod = 0x80;
16280 }
16281
16282 = op->reg;
16283 if (op->reg2 != -1)
16284 reg1 = 4;
16285 g(mod + (reg << 3) + reg1);
16286 if (reg1 == 4) {
16287
16288 = op->reg2;
16289 if (reg2 == -1)
16290 reg2 = 4;
16291 ((op->shift << 6) + (reg2 << 3) + sib_reg1);
16292 }
16293
16294
16295 if (mod == 0x40) {
16296 g(op->e.v);
16297 } else if (mod == 0x80 || op->reg == -1) {
16298 gen_expr32(&op->e);
16299 }
16300 }
16301 }
16302
16303 static void asm_opcode(TCCState *s1, int opcode)
16304 {
16305 const ASMInstr *pa;
16306 int i, modrm_index, reg, v, op1, is_short_jmp;
16307 int nb_ops, s, ss;
16308 Operand ops[MAX_OPERANDS], *pop;
16309 int op_type[3];
16310
16311
16312 = ops;
16313 nb_ops = 0;
16314 for(;;) {
16315 if (tok == ';' || tok == TOK_LINEFEED)
16316 break;
16317 if (nb_ops >= MAX_OPERANDS) {
16318 error("incorrect number of operands");
16319 }
16320 parse_operand(s1, pop);
16321 pop++;
16322 nb_ops++;
16323 if (tok != ',')
16324 break;
16325 next();
16326 }
16327
16328 is_short_jmp = 0;
16329 s = 0;
16330
16331
16332
16333 for(pa = asm_instrs; pa->sym != 0; pa++) {
16334 s = 0;
16335 if (pa->instr_type & OPC_FARITH) {
16336 v = opcode - pa->sym;
16337 if (!((unsigned)v < 8 * 6 && (v % 6) == 0))
16338 continue;
16339 } else if (pa->instr_type & OPC_ARITH) {
16340 if (!(opcode >= pa->sym && opcode < pa->sym + 8 * 4))
16341 continue;
16342 goto compute_size;
16343 } else if (pa->instr_type & OPC_SHIFT) {
16344 if (!(opcode >= pa->sym && opcode < pa->sym + 7 * 4))
16345 continue;
16346 goto compute_size;
16347 } else if (pa->instr_type & OPC_TEST) {
16348 if (!(opcode >= pa->sym && opcode < pa->sym + NB_TEST_OPCODES))
16349 continue;
16350 } else if (pa->instr_type & OPC_B) {
16351 if (!(opcode >= pa->sym && opcode <= pa->sym + 3))
16352 continue;
16353 compute_size:
16354 s = (opcode - pa->sym) & 3;
16355 } else if (pa->instr_type & OPC_WL) {
16356 if (!(opcode >= pa->sym && opcode <= pa->sym + 2))
16357 continue;
16358 s = opcode - pa->sym + 1;
16359 } else {
16360 if (pa->sym != opcode)
16361 continue;
16362 }
16363 if (pa->nb_ops != nb_ops)
16364 continue;
16365
16366 for(i = 0; i < nb_ops; i++) {
16367 int op1, op2;
16368 op1 = pa->op_type[i];
16369 op2 = op1 & 0x1f;
16370 switch(op2) {
16371 case OPT_IM:
16372 v = OP_IM8 | OP_IM16 | OP_IM32;
16373 break;
16374 case OPT_REG:
16375 v = OP_REG8 | OP_REG16 | OP_REG32;
16376 break;
16377 case OPT_REGW:
16378 v = OP_REG16 | OP_REG32;
16379 break;
16380 case OPT_IMW:
16381 v = OP_IM16 | OP_IM32;
16382 break;
16383 default:
16384 v = 1 << op2;
16385 break;
16386 }
16387 if (op1 & OPT_EA)
16388 v |= OP_EA;
16389 op_type[i] = v;
16390 if ((ops[i].type & v) == 0)
16391 goto next;
16392 }
16393
16394 break;
16395 next: ;
16396 }
16397 if (pa->sym == 0) {
16398 if (opcode >= TOK_ASM_pusha && opcode <= TOK_ASM_emms) {
16399 int b;
16400 b = op0_codes[opcode - TOK_ASM_pusha];
16401 if (b & 0xff00)
16402 g(b >> 8);
16403 g(b);
16404 return;
16405 } else {
16406 error("unknown opcode '%s'",
16407 get_tok_str(opcode, NULL));
16408 }
16409 }
16410
16411 if (s == 3) {
16412 for(i = 0; s == 3 && i < nb_ops; i++) {
16413 if ((ops[i].type & OP_REG) && !(op_type[i] & (OP_CL | OP_DX)))
16414 s = reg_to_size[ops[i].type & OP_REG];
16415 }
16416 if (s == 3) {
16417 if ((opcode == TOK_ASM_push || opcode == TOK_ASM_pop) &&
16418 (ops[0].type & (OP_SEG | OP_IM8S | OP_IM32)))
16419 s = 2;
16420 else
16421 error("cannot infer opcode suffix");
16422 }
16423 }
16424
16425
16426 = s;
16427 if (s == 1 || (pa->instr_type & OPC_D16))
16428 g(WORD_PREFIX_OPCODE);
16429 else if (s == 2)
16430 s = 1;
16431
16432 if (pa->instr_type & OPC_FWAIT)
16433 g(0x9b);
16434
16435 v = pa->opcode;
16436 if (v == 0x69 || v == 0x69) {
16437
16438 = 3;
16439 ops[2] = ops[1];
16440 } else if (v == 0xcd && ops[0].e.v == 3 && !ops[0].e.sym) {
16441 v--;
16442 = 0;
16443 } else if ((v == 0x06 || v == 0x07)) {
16444 if (ops[0].reg >= 4) {
16445
16446 = 0x0fa0 + (v - 0x06) + ((ops[0].reg - 4) << 3);
16447 } else {
16448 v += ops[0].reg << 3;
16449 }
16450 nb_ops = 0;
16451 } else if (v <= 0x05) {
16452
16453 += ((opcode - TOK_ASM_addb) >> 2) << 3;
16454 } else if ((pa->instr_type & (OPC_FARITH | OPC_MODRM)) == OPC_FARITH) {
16455
16456 += ((opcode - pa->sym) / 6) << 3;
16457 }
16458 if (pa->instr_type & OPC_REG) {
16459 for(i = 0; i < nb_ops; i++) {
16460 if (op_type[i] & (OP_REG | OP_ST)) {
16461 v += ops[i].reg;
16462 break;
16463 }
16464 }
16465
16466 if (pa->opcode == 0xb0 && s >= 1)
16467 v += 7;
16468 }
16469 if (pa->instr_type & OPC_B)
16470 v += s;
16471 if (pa->instr_type & OPC_TEST)
16472 v += test_bits[opcode - pa->sym];
16473 if (pa->instr_type & OPC_SHORTJMP) {
16474 Sym *sym;
16475 int jmp_disp;
16476
16477
16478 = ops[0].e.sym;
16479 if (!sym)
16480 goto no_short_jump;
16481 if (sym->r != cur_text_section->sh_num)
16482 goto no_short_jump;
16483 jmp_disp = ops[0].e.v + (long)sym->next - ind - 2;
16484 if (jmp_disp == (int8_t)jmp_disp) {
16485
16486 = 1;
16487 ops[0].e.v = jmp_disp;
16488 } else {
16489 no_short_jump:
16490 if (pa->instr_type & OPC_JMP) {
16491
16492
16493 if (v == 0xeb)
16494 v = 0xe9;
16495 else
16496 v += 0x0f10;
16497 } else {
16498 error("invalid displacement");
16499 }
16500 }
16501 }
16502 op1 = v >> 8;
16503 if (op1)
16504 g(op1);
16505 g(v);
16506
16507
16508 = 0;
16509 if (pa->instr_type & OPC_SHIFT) {
16510 reg = (opcode - pa->sym) >> 2;
16511 if (reg == 6)
16512 reg = 7;
16513 } else if (pa->instr_type & OPC_ARITH) {
16514 reg = (opcode - pa->sym) >> 2;
16515 } else if (pa->instr_type & OPC_FARITH) {
16516 reg = (opcode - pa->sym) / 6;
16517 } else {
16518 reg = (pa->instr_type >> OPC_GROUP_SHIFT) & 7;
16519 }
16520 if (pa->instr_type & OPC_MODRM) {
16521
16522 for(i = 0;i < nb_ops; i++) {
16523 if (op_type[i] & OP_EA)
16524 goto modrm_found;
16525 }
16526
16527 for(i = 0;i < nb_ops; i++) {
16528 if (op_type[i] & (OP_REG | OP_MMX | OP_SSE | OP_INDIR))
16529 goto modrm_found;
16530 }
16531 #ifdef ASM_DEBUG
16532 error("bad op table");
16533 #endif
16534 modrm_found:
16535 modrm_index = i;
16536
16537
16538 for(i = 0;i < nb_ops; i++) {
16539 v = op_type[i];
16540 if (i != modrm_index &&
16541 (v & (OP_REG | OP_MMX | OP_SSE | OP_CR | OP_TR | OP_DB | OP_SEG))) {
16542 reg = ops[i].reg;
16543 break;
16544 }
16545 }
16546
16547 asm_modrm(reg, &ops[modrm_index]);
16548 }
16549
16550
16551 if (pa->opcode == 0x9a || pa->opcode == 0xea) {
16552
16553 (&ops[1].e);
16554 if (ops[0].e.sym)
16555 error("cannot relocate");
16556 gen_le16(ops[0].e.v);
16557 } else {
16558 for(i = 0;i < nb_ops; i++) {
16559 v = op_type[i];
16560 if (v & (OP_IM8 | OP_IM16 | OP_IM32 | OP_IM8S | OP_ADDR)) {
16561
16562
16563 if (v == (OP_IM8 | OP_IM16 | OP_IM32) ||
16564 v == (OP_IM16 | OP_IM32)) {
16565 if (ss == 0)
16566 v = OP_IM8;
16567 else if (ss == 1)
16568 v = OP_IM16;
16569 else
16570 v = OP_IM32;
16571 }
16572 if (v & (OP_IM8 | OP_IM8S)) {
16573 if (ops[i].e.sym)
16574 goto error_relocate;
16575 g(ops[i].e.v);
16576 } else if (v & OP_IM16) {
16577 if (ops[i].e.sym) {
16578 error_relocate:
16579 error("cannot relocate");
16580 }
16581 gen_le16(ops[i].e.v);
16582 } else {
16583 if (pa->instr_type & (OPC_JMP | OPC_SHORTJMP)) {
16584 if (is_short_jmp)
16585 g(ops[i].e.v);
16586 else
16587 gen_disp32(&ops[i].e);
16588 } else {
16589 gen_expr32(&ops[i].e);
16590 }
16591 }
16592 }
16593 }
16594 }
16595 }
16596
16597 #define NB_SAVED_REGS 3
16598 #define NB_ASM_REGS 8
16599
16600
16601
16602 static inline int constraint_priority(const char *str)
16603 {
16604 int priority, c, pr;
16605
16606
16607 = 0;
16608 for(;;) {
16609 c = *str;
16610 if (c == '\0')
16611 break;
16612 str++;
16613 switch(c) {
16614 case 'A':
16615 pr = 0;
16616 break;
16617 case 'a':
16618 case 'b':
16619 case 'c':
16620 case 'd':
16621 case 'S':
16622 case 'D':
16623 pr = 1;
16624 break;
16625 case 'q':
16626 pr = 2;
16627 break;
16628 case 'r':
16629 pr = 3;
16630 break;
16631 case 'N':
16632 case 'M':
16633 case 'I':
16634 case 'i':
16635 case 'm':
16636 case 'g':
16637 pr = 4;
16638 break;
16639 default:
16640 error("unknown constraint '%c'", c);
16641 pr = 0;
16642 }
16643 if (pr > priority)
16644 priority = pr;
16645 }
16646 return priority;
16647 }
16648
16649 static const char *skip_constraint_modifiers(const char *p)
16650 {
16651 while (*p == '=' || *p == '&' || *p == '+' || *p == '%')
16652 p++;
16653 return p;
16654 }
16655
16656 #define REG_OUT_MASK 0x01
16657 #define REG_IN_MASK 0x02
16658
16659 #define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask)
16660
16661 static void asm_compute_constraints(ASMOperand *operands,
16662 int nb_operands, int nb_outputs,
16663 const uint8_t *clobber_regs,
16664 int *pout_reg)
16665 {
16666 ASMOperand *op;
16667 int sorted_op[MAX_ASM_OPERANDS];
16668 int i, j, k, p1, p2, tmp, reg, c, reg_mask;
16669 const char *str;
16670 uint8_t regs_allocated[NB_ASM_REGS];
16671
16672
16673 for(i=0;i<nb_operands;i++) {
16674 op = &operands[i];
16675 op->input_index = -1;
16676 op->ref_index = -1;
16677 op->reg = -1;
16678 op->is_memory = 0;
16679 op->is_rw = 0;
16680 }
16681
16682
16683 for(i=0;i<nb_operands;i++) {
16684 op = &operands[i];
16685 str = op->constraint;
16686 str = skip_constraint_modifiers(str);
16687 if (isnum(*str) || *str == '[') {
16688
16689 = find_constraint(operands, nb_operands, str, NULL);
16690 if ((unsigned)k >= i || i < nb_outputs)
16691 error("invalid reference in constraint %d ('%s')",
16692 i, str);
16693 op->ref_index = k;
16694 if (operands[k].input_index >= 0)
16695 error("cannot reference twice the same operand");
16696 operands[k].input_index = i;
16697 op->priority = 5;
16698 } else {
16699 op->priority = constraint_priority(str);
16700 }
16701 }
16702
16703
16704 for(i=0;i<nb_operands;i++)
16705 sorted_op[i] = i;
16706 for(i=0;i<nb_operands - 1;i++) {
16707 for(j=i+1;j<nb_operands;j++) {
16708 p1 = operands[sorted_op[i]].priority;
16709 p2 = operands[sorted_op[j]].priority;
16710 if (p2 < p1) {
16711 tmp = sorted_op[i];
16712 sorted_op[i] = sorted_op[j];
16713 sorted_op[j] = tmp;
16714 }
16715 }
16716 }
16717
16718 for(i = 0;i < NB_ASM_REGS; i++) {
16719 if (clobber_regs[i])
16720 regs_allocated[i] = REG_IN_MASK | REG_OUT_MASK;
16721 else
16722 regs_allocated[i] = 0;
16723 }
16724
16725 [4] = REG_IN_MASK | REG_OUT_MASK;
16726
16727 [5] = REG_IN_MASK | REG_OUT_MASK;
16728
16729
16730 for(i=0;i<nb_operands;i++) {
16731 j = sorted_op[i];
16732 op = &operands[j];
16733 str = op->constraint;
16734
16735 if (op->ref_index >= 0)
16736 continue;
16737
16738 if (op->input_index >= 0) {
16739 reg_mask = REG_IN_MASK | REG_OUT_MASK;
16740 } else if (j < nb_outputs) {
16741 reg_mask = REG_OUT_MASK;
16742 } else {
16743 reg_mask = REG_IN_MASK;
16744 }
16745 try_next:
16746 c = *str++;
16747 switch(c) {
16748 case '=':
16749 goto try_next;
16750 case '+':
16751 op->is_rw = 1;
16752
16753 case '&':
16754 if (j >= nb_outputs)
16755 error("'%c' modifier can only be applied to outputs", c);
16756 reg_mask = REG_IN_MASK | REG_OUT_MASK;
16757 goto try_next;
16758 case 'A':
16759
16760 if (is_reg_allocated(TREG_EAX) ||
16761 is_reg_allocated(TREG_EDX))
16762 goto try_next;
16763 op->is_llong = 1;
16764 op->reg = TREG_EAX;
16765 regs_allocated[TREG_EAX] |= reg_mask;
16766 regs_allocated[TREG_EDX] |= reg_mask;
16767 break;
16768 case 'a':
16769 reg = TREG_EAX;
16770 goto alloc_reg;
16771 case 'b':
16772 reg = 3;
16773 goto alloc_reg;
16774 case 'c':
16775 reg = TREG_ECX;
16776 goto alloc_reg;
16777 case 'd':
16778 reg = TREG_EDX;
16779 goto alloc_reg;
16780 case 'S':
16781 reg = 6;
16782 goto alloc_reg;
16783 case 'D':
16784 reg = 7;
16785 alloc_reg:
16786 if (is_reg_allocated(reg))
16787 goto try_next;
16788 goto reg_found;
16789 case 'q':
16790
16791 for(reg = 0; reg < 4; reg++) {
16792 if (!is_reg_allocated(reg))
16793 goto reg_found;
16794 }
16795 goto try_next;
16796 case 'r':
16797
16798 for(reg = 0; reg < 8; reg++) {
16799 if (!is_reg_allocated(reg))
16800 goto reg_found;
16801 }
16802 goto try_next;
16803 reg_found:
16804
16805 ->is_llong = 0;
16806 op->reg = reg;
16807 regs_allocated[reg] |= reg_mask;
16808 break;
16809 case 'i':
16810 if (!((op->vt->r & (VT_VALMASK | VT_LVAL)) == VT_CONST))
16811 goto try_next;
16812 break;
16813 case 'I':
16814 case 'N':
16815 case 'M':
16816 if (!((op->vt->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST))
16817 goto try_next;
16818 break;
16819 case 'm':
16820 case 'g':
16821
16822
16823
16824
16825
16826
16827
16828
16829 if (j < nb_outputs || c == 'm') {
16830 if ((op->vt->r & VT_VALMASK) == VT_LLOCAL) {
16831
16832 for(reg = 0; reg < 8; reg++) {
16833 if (!(regs_allocated[reg] & REG_IN_MASK))
16834 goto reg_found1;
16835 }
16836 goto try_next;
16837 reg_found1:
16838
16839 [reg] |= REG_IN_MASK;
16840 op->reg = reg;
16841 op->is_memory = 1;
16842 }
16843 }
16844 break;
16845 default:
16846 error("asm constraint %d ('%s') could not be satisfied",
16847 j, op->constraint);
16848 break;
16849 }
16850
16851 if (op->input_index >= 0) {
16852 operands[op->input_index].reg = op->reg;
16853 operands[op->input_index].is_llong = op->is_llong;
16854 }
16855 }
16856
16857
16858
16859 *pout_reg = -1;
16860 for(i=0;i<nb_operands;i++) {
16861 op = &operands[i];
16862 if (op->reg >= 0 &&
16863 (op->vt->r & VT_VALMASK) == VT_LLOCAL &&
16864 !op->is_memory) {
16865 for(reg = 0; reg < 8; reg++) {
16866 if (!(regs_allocated[reg] & REG_OUT_MASK))
16867 goto reg_found2;
16868 }
16869 error("could not find free output register for reloading");
16870 reg_found2:
16871 *pout_reg = reg;
16872 break;
16873 }
16874 }
16875
16876
16877 #ifdef ASM_DEBUG
16878 for(i=0;i<nb_operands;i++) {
16879 j = sorted_op[i];
16880 op = &operands[j];
16881 printf("%%%d [%s]: \"%s\" r=0x%04x reg=%d\n",
16882 j,
16883 op->id ? get_tok_str(op->id, NULL) : "",
16884 op->constraint,
16885 op->vt->r,
16886 op->reg);
16887 }
16888 if (*pout_reg >= 0)
16889 printf("out_reg=%d\n", *pout_reg);
16890 #endif
16891 }
16892
16893 static void subst_asm_operand(CString *add_str,
16894 SValue *sv, int modifier)
16895 {
16896 int r, reg, size, val;
16897 char buf[64];
16898
16899 r = sv->r;
16900 if ((r & VT_VALMASK) == VT_CONST) {
16901 if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n')
16902 cstr_ccat(add_str, '$');
16903 if (r & VT_SYM) {
16904 cstr_cat(add_str, get_tok_str(sv->sym->v, NULL));
16905 if (sv->c.i != 0) {
16906 cstr_ccat(add_str, '+');
16907 } else {
16908 return;
16909 }
16910 }
16911 val = sv->c.i;
16912 if (modifier == 'n')
16913 val = -val;
16914 snprintf(buf, sizeof(buf), "%d", sv->c.i);
16915 cstr_cat(add_str, buf);
16916 } else if ((r & VT_VALMASK) == VT_LOCAL) {
16917 snprintf(buf, sizeof(buf), "%d(%%ebp)", sv->c.i);
16918 cstr_cat(add_str, buf);
16919 } else if (r & VT_LVAL) {
16920 reg = r & VT_VALMASK;
16921 if (reg >= VT_CONST)
16922 error("internal compiler error");
16923 snprintf(buf, sizeof(buf), "(%%%s)",
16924 get_tok_str(TOK_ASM_eax + reg, NULL));
16925 cstr_cat(add_str, buf);
16926 } else {
16927
16928 = r & VT_VALMASK;
16929 if (reg >= VT_CONST)
16930 error("internal compiler error");
16931
16932
16933 if ((sv->type.t & VT_BTYPE) == VT_BYTE)
16934 size = 1;
16935 else if ((sv->type.t & VT_BTYPE) == VT_SHORT)
16936 size = 2;
16937 else
16938 size = 4;
16939 if (size == 1 && reg >= 4)
16940 size = 4;
16941
16942 if (modifier == 'b') {
16943 if (reg >= 4)
16944 error("cannot use byte register");
16945 size = 1;
16946 } else if (modifier == 'h') {
16947 if (reg >= 4)
16948 error("cannot use byte register");
16949 size = -1;
16950 } else if (modifier == 'w') {
16951 size = 2;
16952 }
16953
16954 switch(size) {
16955 case -1:
16956 reg = TOK_ASM_ah + reg;
16957 break;
16958 case 1:
16959 reg = TOK_ASM_al + reg;
16960 break;
16961 case 2:
16962 reg = TOK_ASM_ax + reg;
16963 break;
16964 default:
16965 reg = TOK_ASM_eax + reg;
16966 break;
16967 }
16968 snprintf(buf, sizeof(buf), "%%%s", get_tok_str(reg, NULL));
16969 cstr_cat(add_str, buf);
16970 }
16971 }
16972
16973
16974 static void asm_gen_code(ASMOperand *operands, int nb_operands,
16975 int nb_outputs, int is_output,
16976 uint8_t *clobber_regs,
16977 int out_reg)
16978 {
16979 uint8_t regs_allocated[NB_ASM_REGS];
16980 ASMOperand *op;
16981 int i, reg;
16982 static uint8_t reg_saved[NB_SAVED_REGS] = { 3, 6, 7 };
16983
16984
16985 (regs_allocated, clobber_regs, sizeof(regs_allocated));
16986 for(i = 0; i < nb_operands;i++) {
16987 op = &operands[i];
16988 if (op->reg >= 0)
16989 regs_allocated[op->reg] = 1;
16990 }
16991 if (!is_output) {
16992
16993 for(i = 0; i < NB_SAVED_REGS; i++) {
16994 reg = reg_saved[i];
16995 if (regs_allocated[reg])
16996 g(0x50 + reg);
16997 }
16998
16999
17000 for(i = 0; i < nb_operands; i++) {
17001 op = &operands[i];
17002 if (op->reg >= 0) {
17003 if ((op->vt->r & VT_VALMASK) == VT_LLOCAL &&
17004 op->is_memory) {
17005
17006
17007 ;
17008 sv = *op->vt;
17009 sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL;
17010 load(op->reg, &sv);
17011 } else if (i >= nb_outputs || op->is_rw) {
17012
17013 (op->reg, op->vt);
17014 if (op->is_llong) {
17015 SValue sv;
17016 sv = *op->vt;
17017 sv.c.ul += 4;
17018 load(TREG_EDX, &sv);
17019 }
17020 }
17021 }
17022 }
17023 } else {
17024
17025 for(i = 0 ; i < nb_outputs; i++) {
17026 op = &operands[i];
17027 if (op->reg >= 0) {
17028 if ((op->vt->r & VT_VALMASK) == VT_LLOCAL) {
17029 if (!op->is_memory) {
17030 SValue sv;
17031 sv = *op->vt;
17032 sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL;
17033 load(out_reg, &sv);
17034
17035 sv.r = (sv.r & ~VT_VALMASK) | out_reg;
17036 store(op->reg, &sv);
17037 }
17038 } else {
17039 store(op->reg, op->vt);
17040 if (op->is_llong) {
17041 SValue sv;
17042 sv = *op->vt;
17043 sv.c.ul += 4;
17044 store(TREG_EDX, &sv);
17045 }
17046 }
17047 }
17048 }
17049
17050 for(i = NB_SAVED_REGS - 1; i >= 0; i--) {
17051 reg = reg_saved[i];
17052 if (regs_allocated[reg])
17053 g(0x58 + reg);
17054 }
17055 }
17056 }
17057
17058 static void asm_clobber(uint8_t *clobber_regs, const char *str)
17059 {
17060 int reg;
17061 TokenSym *ts;
17062
17063 if (!strcmp(str, "memory") ||
17064 !strcmp(str, "cc"))
17065 return;
17066 ts = tok_alloc(str, strlen(str));
17067 reg = ts->tok;
17068 if (reg >= TOK_ASM_eax && reg <= TOK_ASM_edi) {
17069 reg -= TOK_ASM_eax;
17070 } else if (reg >= TOK_ASM_ax && reg <= TOK_ASM_di) {
17071 reg -= TOK_ASM_ax;
17072 } else {
17073 error("invalid clobber register '%s'", str);
17074 }
17075 clobber_regs[reg] = 1;
17076 }
17077
17078 #endif
17079
17080
17081
17082
17083
17084
17085
17086
17087
17088
17089
17090
17091
17092
17093
17094
17095
17096
17097
17098
17099
17100
17101
17102 static int asm_get_local_label_name(TCCState *s1, unsigned int n)
17103 {
17104 char buf[64];
17105 TokenSym *ts;
17106
17107 snprintf(buf, sizeof(buf), "L..%u", n);
17108 ts = tok_alloc(buf, strlen(buf));
17109 return ts->tok;
17110 }
17111
17112 static void asm_expr(TCCState *s1, ExprValue *pe);
17113
17114
17115
17116
17117 static void asm_expr_unary(TCCState *s1, ExprValue *pe)
17118 {
17119 Sym *sym;
17120 int op, n, label;
17121 const char *p;
17122
17123 switch(tok) {
17124 case TOK_PPNUM:
17125 p = tokc.cstr->data;
17126 n = strtoul(p, (char **)&p, 0);
17127 if (*p == 'b' || *p == 'f') {
17128
17129 = asm_get_local_label_name(s1, n);
17130 sym = label_find(label);
17131 if (*p == 'b') {
17132
17133 if (sym && sym->r == 0)
17134 sym = sym->prev_tok;
17135 if (!sym)
17136 error("local label '%d' not found backward", n);
17137 } else {
17138
17139 if (!sym || sym->r) {
17140
17141 = label_push(&s1->asm_labels, label, 0);
17142 sym->type.t = VT_STATIC | VT_VOID;
17143 }
17144 }
17145 pe->v = 0;
17146 pe->sym = sym;
17147 } else if (*p == '\0') {
17148 pe->v = n;
17149 pe->sym = NULL;
17150 } else {
17151 error("invalid number syntax");
17152 }
17153 next();
17154 break;
17155 case '+':
17156 next();
17157 asm_expr_unary(s1, pe);
17158 break;
17159 case '-':
17160 case '~':
17161 op = tok;
17162 next();
17163 asm_expr_unary(s1, pe);
17164 if (pe->sym)
17165 error("invalid operation with label");
17166 if (op == '-')
17167 pe->v = -pe->v;
17168 else
17169 pe->v = ~pe->v;
17170 break;
17171 case TOK_CCHAR:
17172 case TOK_LCHAR:
17173 pe->v = tokc.i;
17174 pe->sym = NULL;
17175 next();
17176 break;
17177 case '(':
17178 next();
17179 asm_expr(s1, pe);
17180 skip(')');
17181 break;
17182 default:
17183 if (tok >= TOK_IDENT) {
17184
17185 = label_find(tok);
17186 if (!sym) {
17187 sym = label_push(&s1->asm_labels, tok, 0);
17188
17189 ->type.t = VT_VOID;
17190 }
17191 if (sym->r == SHN_ABS) {
17192
17193 ->v = (long)sym->next;
17194 pe->sym = NULL;
17195 } else {
17196 pe->v = 0;
17197 pe->sym = sym;
17198 }
17199 next();
17200 } else {
17201 error("bad expression syntax [%s]", get_tok_str(tok, &tokc));
17202 }
17203 break;
17204 }
17205 }
17206
17207 static void asm_expr_prod(TCCState *s1, ExprValue *pe)
17208 {
17209 int op;
17210 ExprValue e2;
17211
17212 asm_expr_unary(s1, pe);
17213 for(;;) {
17214 op = tok;
17215 if (op != '*' && op != '/' && op != '%' &&
17216 op != TOK_SHL && op != TOK_SAR)
17217 break;
17218 next();
17219 asm_expr_unary(s1, &e2);
17220 if (pe->sym || e2.sym)
17221 error("invalid operation with label");
17222 switch(op) {
17223 case '*':
17224 pe->v *= e2.v;
17225 break;
17226 case '/':
17227 if (e2.v == 0) {
17228 div_error:
17229 error("division by zero");
17230 }
17231 pe->v /= e2.v;
17232 break;
17233 case '%':
17234 if (e2.v == 0)
17235 goto div_error;
17236 pe->v %= e2.v;
17237 break;
17238 case TOK_SHL:
17239 pe->v <<= e2.v;
17240 break;
17241 default:
17242 case TOK_SAR:
17243 pe->v >>= e2.v;
17244 break;
17245 }
17246 }
17247 }
17248
17249 static void asm_expr_logic(TCCState *s1, ExprValue *pe)
17250 {
17251 int op;
17252 ExprValue e2;
17253
17254 asm_expr_prod(s1, pe);
17255 for(;;) {
17256 op = tok;
17257 if (op != '&' && op != '|' && op != '^')
17258 break;
17259 next();
17260 asm_expr_prod(s1, &e2);
17261 if (pe->sym || e2.sym)
17262 error("invalid operation with label");
17263 switch(op) {
17264 case '&':
17265 pe->v &= e2.v;
17266 break;
17267 case '|':
17268 pe->v |= e2.v;
17269 break;
17270 default:
17271 case '^':
17272 pe->v ^= e2.v;
17273 break;
17274 }
17275 }
17276 }
17277
17278 static inline void asm_expr_sum(TCCState *s1, ExprValue *pe)
17279 {
17280 int op;
17281 ExprValue e2;
17282
17283 asm_expr_logic(s1, pe);
17284 for(;;) {
17285 op = tok;
17286 if (op != '+' && op != '-')
17287 break;
17288 next();
17289 asm_expr_logic(s1, &e2);
17290 if (op == '+') {
17291 if (pe->sym != NULL && e2.sym != NULL)
17292 goto cannot_relocate;
17293 pe->v += e2.v;
17294 if (pe->sym == NULL && e2.sym != NULL)
17295 pe->sym = e2.sym;
17296 } else {
17297 pe->v -= e2.v;
17298
17299
17300 if (!pe->sym && !e2.sym) {
17301
17302 } else if (pe->sym && !e2.sym) {
17303
17304 } else if (pe->sym && e2.sym) {
17305 if (pe->sym == e2.sym) {
17306
17307 } else if (pe->sym->r == e2.sym->r && pe->sym->r != 0) {
17308
17309 ->v += (long)pe->sym->next - (long)e2.sym->next;
17310 } else {
17311 goto cannot_relocate;
17312 }
17313 pe->sym = NULL;
17314 } else {
17315 cannot_relocate:
17316 error("invalid operation with label");
17317 }
17318 }
17319 }
17320 }
17321
17322 static void asm_expr(TCCState *s1, ExprValue *pe)
17323 {
17324 asm_expr_sum(s1, pe);
17325 }
17326
17327 static int asm_int_expr(TCCState *s1)
17328 {
17329 ExprValue e;
17330 asm_expr(s1, &e);
17331 if (e.sym)
17332 expect("constant");
17333 return e.v;
17334 }
17335
17336
17337
17338 static void asm_new_label1(TCCState *s1, int label, int is_local,
17339 int sh_num, long value)
17340 {
17341 Sym *sym;
17342
17343 sym = label_find(label);
17344 if (sym) {
17345 if (sym->r) {
17346
17347 if (!is_local) {
17348 error("assembler label '%s' already defined",
17349 get_tok_str(label, NULL));
17350 } else {
17351
17352 goto new_label;
17353 }
17354 }
17355 } else {
17356 new_label:
17357 sym = label_push(&s1->asm_labels, label, 0);
17358 sym->type.t = VT_STATIC | VT_VOID;
17359 }
17360 sym->r = sh_num;
17361 sym->next = (void *)value;
17362 }
17363
17364 static void asm_new_label(TCCState *s1, int label, int is_local)
17365 {
17366 asm_new_label1(s1, label, is_local, cur_text_section->sh_num, ind);
17367 }
17368
17369 static void asm_free_labels(TCCState *st)
17370 {
17371 Sym *s, *s1;
17372 Section *sec;
17373
17374 for(s = st->asm_labels; s != NULL; s = s1) {
17375 s1 = s->prev;
17376
17377 if (s->r) {
17378 if (s->r == SHN_ABS)
17379 sec = SECTION_ABS;
17380 else
17381 sec = st->sections[s->r];
17382 put_extern_sym2(s, sec, (long)s->next, 0, 0);
17383 }
17384
17385 [s->v - TOK_IDENT]->sym_label = NULL;
17386 sym_free(s);
17387 }
17388 st->asm_labels = NULL;
17389 }
17390
17391 static void use_section1(TCCState *s1, Section *sec)
17392 {
17393 cur_text_section->data_offset = ind;
17394 cur_text_section = sec;
17395 ind = cur_text_section->data_offset;
17396 }
17397
17398 static void use_section(TCCState *s1, const char *name)
17399 {
17400 Section *sec;
17401 sec = find_section(s1, name);
17402 use_section1(s1, sec);
17403 }
17404
17405 static void asm_parse_directive(TCCState *s1)
17406 {
17407 int n, offset, v, size, tok1;
17408 Section *sec;
17409 uint8_t *ptr;
17410
17411
17412 ();
17413 sec = cur_text_section;
17414 switch(tok) {
17415 case TOK_ASM_align:
17416 case TOK_ASM_skip:
17417 case TOK_ASM_space:
17418 tok1 = tok;
17419 next();
17420 n = asm_int_expr(s1);
17421 if (tok1 == TOK_ASM_align) {
17422 if (n < 0 || (n & (n-1)) != 0)
17423 error("alignment must be a positive power of two");
17424 offset = (ind + n - 1) & -n;
17425 size = offset - ind;
17426
17427 if (sec->sh_addralign < n)
17428 sec->sh_addralign = n;
17429 } else {
17430 size = n;
17431 }
17432 v = 0;
17433 if (tok == ',') {
17434 next();
17435 v = asm_int_expr(s1);
17436 }
17437 zero_pad:
17438 if (sec->sh_type != SHT_NOBITS) {
17439 sec->data_offset = ind;
17440 ptr = section_ptr_add(sec, size);
17441 memset(ptr, v, size);
17442 }
17443 ind += size;
17444 break;
17445 case TOK_ASM_quad:
17446 next();
17447 for(;;) {
17448 uint64_t vl;
17449 const char *p;
17450
17451 p = tokc.cstr->data;
17452 if (tok != TOK_PPNUM) {
17453 error_constant:
17454 error("64 bit constant");
17455 }
17456 vl = strtoll(p, (char **)&p, 0);
17457 if (*p != '\0')
17458 goto error_constant;
17459 next();
17460 if (sec->sh_type != SHT_NOBITS) {
17461
17462 (vl);
17463 gen_le32(vl >> 32);
17464 } else {
17465 ind += 8;
17466 }
17467 if (tok != ',')
17468 break;
17469 next();
17470 }
17471 break;
17472 case TOK_ASM_byte:
17473 size = 1;
17474 goto asm_data;
17475 case TOK_ASM_word:
17476 case TOK_SHORT:
17477 size = 2;
17478 goto asm_data;
17479 case TOK_LONG:
17480 case TOK_INT:
17481 size = 4;
17482 asm_data:
17483 next();
17484 for(;;) {
17485 ExprValue e;
17486 asm_expr(s1, &e);
17487 if (sec->sh_type != SHT_NOBITS) {
17488 if (size == 4) {
17489 gen_expr32(&e);
17490 } else {
17491 if (e.sym)
17492 expect("constant");
17493 if (size == 1)
17494 g(e.v);
17495 else
17496 gen_le16(e.v);
17497 }
17498 } else {
17499 ind += size;
17500 }
17501 if (tok != ',')
17502 break;
17503 next();
17504 }
17505 break;
17506 case TOK_ASM_fill:
17507 {
17508 int repeat, size, val, i, j;
17509 uint8_t repeat_buf[8];
17510 next();
17511 repeat = asm_int_expr(s1);
17512 if (repeat < 0) {
17513 error("repeat < 0; .fill ignored");
17514 break;
17515 }
17516 size = 1;
17517 val = 0;
17518 if (tok == ',') {
17519 next();
17520 size = asm_int_expr(s1);
17521 if (size < 0) {
17522 error("size < 0; .fill ignored");
17523 break;
17524 }
17525 if (size > 8)
17526 size = 8;
17527 if (tok == ',') {
17528 next();
17529 val = asm_int_expr(s1);
17530 }
17531 }
17532
17533 [0] = val;
17534 repeat_buf[1] = val >> 8;
17535 repeat_buf[2] = val >> 16;
17536 repeat_buf[3] = val >> 24;
17537 repeat_buf[4] = 0;
17538 repeat_buf[5] = 0;
17539 repeat_buf[6] = 0;
17540 repeat_buf[7] = 0;
17541 for(i = 0; i < repeat; i++) {
17542 for(j = 0; j < size; j++) {
17543 g(repeat_buf[j]);
17544 }
17545 }
17546 }
17547 break;
17548 case TOK_ASM_org:
17549 {
17550 unsigned long n;
17551 next();
17552
17553 = asm_int_expr(s1);
17554 if (n < ind)
17555 error("attempt to .org backwards");
17556 v = 0;
17557 size = n - ind;
17558 goto zero_pad;
17559 }
17560 break;
17561 case TOK_ASM_globl:
17562 case TOK_ASM_global:
17563 {
17564 Sym *sym;
17565
17566 next();
17567 sym = label_find(tok);
17568 if (!sym) {
17569 sym = label_push(&s1->asm_labels, tok, 0);
17570 sym->type.t = VT_VOID;
17571 }
17572 sym->type.t &= ~VT_STATIC;
17573 next();
17574 }
17575 break;
17576 case TOK_ASM_string:
17577 case TOK_ASM_ascii:
17578 case TOK_ASM_asciz:
17579 {
17580 const uint8_t *p;
17581 int i, size, t;
17582
17583 t = tok;
17584 next();
17585 for(;;) {
17586 if (tok != TOK_STR)
17587 expect("string constant");
17588 p = tokc.cstr->data;
17589 size = tokc.cstr->size;
17590 if (t == TOK_ASM_ascii && size > 0)
17591 size--;
17592 for(i = 0; i < size; i++)
17593 g(p[i]);
17594 next();
17595 if (tok == ',') {
17596 next();
17597 } else if (tok != TOK_STR) {
17598 break;
17599 }
17600 }
17601 }
17602 break;
17603 case TOK_ASM_text:
17604 case TOK_ASM_data:
17605 case TOK_ASM_bss:
17606 {
17607 char sname[64];
17608 tok1 = tok;
17609 n = 0;
17610 next();
17611 if (tok != ';' && tok != TOK_LINEFEED) {
17612 n = asm_int_expr(s1);
17613 next();
17614 }
17615 sprintf(sname, (n?".%s%d":".%s"), get_tok_str(tok1, NULL), n);
17616 use_section(s1, sname);
17617 }
17618 break;
17619 case TOK_SECTION1:
17620 {
17621 char sname[256];
17622
17623
17624 ();
17625 sname[0] = '\0';
17626 while (tok != ';' && tok != TOK_LINEFEED && tok != ',') {
17627 if (tok == TOK_STR)
17628 pstrcat(sname, sizeof(sname), tokc.cstr->data);
17629 else
17630 pstrcat(sname, sizeof(sname), get_tok_str(tok, NULL));
17631 next();
17632 }
17633 if (tok == ',') {
17634
17635 ();
17636 if (tok != TOK_STR)
17637 expect("string constant");
17638 next();
17639 }
17640 last_text_section = cur_text_section;
17641 use_section(s1, sname);
17642 }
17643 break;
17644 case TOK_ASM_previous:
17645 {
17646 Section *sec;
17647 next();
17648 if (!last_text_section)
17649 error("no previous section referenced");
17650 sec = cur_text_section;
17651 use_section1(s1, last_text_section);
17652 last_text_section = sec;
17653 }
17654 break;
17655 default:
17656 error("unknown assembler directive '.%s'", get_tok_str(tok, NULL));
17657 break;
17658 }
17659 }
17660
17661
17662
17663 static int tcc_assemble_internal(TCCState *s1, int do_preprocess)
17664 {
17665 int opcode;
17666
17667 #if 0
17668
17669 {
17670 const ASMInstr *pa;
17671 int freq[4];
17672 int op_vals[500];
17673 int nb_op_vals, i, j;
17674
17675 nb_op_vals = 0;
17676 memset(freq, 0, sizeof(freq));
17677 for(pa = asm_instrs; pa->sym != 0; pa++) {
17678 freq[pa->nb_ops]++;
17679 for(i=0;i<pa->nb_ops;i++) {
17680 for(j=0;j<nb_op_vals;j++) {
17681 if (pa->op_type[i] == op_vals[j])
17682 goto found;
17683 }
17684 op_vals[nb_op_vals++] = pa->op_type[i];
17685 found: ;
17686 }
17687 }
17688 for(i=0;i<nb_op_vals;i++) {
17689 int v = op_vals[i];
17690 if ((v & (v - 1)) != 0)
17691 printf("%3d: %08x\n", i, v);
17692 }
17693 printf("size=%d nb=%d f0=%d f1=%d f2=%d f3=%d\n",
17694 sizeof(asm_instrs), sizeof(asm_instrs) / sizeof(ASMInstr),
17695 freq[0], freq[1], freq[2], freq[3]);
17696 }
17697 #endif
17698
17699
17700
17701 = file->buf_ptr[0];
17702 tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
17703 parse_flags = PARSE_FLAG_ASM_COMMENTS;
17704 if (do_preprocess)
17705 parse_flags |= PARSE_FLAG_PREPROCESS;
17706 next();
17707 for(;;) {
17708 if (tok == TOK_EOF)
17709 break;
17710 parse_flags |= PARSE_FLAG_LINEFEED;
17711 redo:
17712 if (tok == '#') {
17713
17714 while (tok != TOK_LINEFEED)
17715 next();
17716 } else if (tok == '.') {
17717 asm_parse_directive(s1);
17718 } else if (tok == TOK_PPNUM) {
17719 const char *p;
17720 int n;
17721 p = tokc.cstr->data;
17722 n = strtoul(p, (char **)&p, 10);
17723 if (*p != '\0')
17724 expect("':'");
17725
17726 (s1, asm_get_local_label_name(s1, n), 1);
17727 next();
17728 skip(':');
17729 goto redo;
17730 } else if (tok >= TOK_IDENT) {
17731
17732 = tok;
17733 next();
17734 if (tok == ':') {
17735
17736 (s1, opcode, 0);
17737 next();
17738 goto redo;
17739 } else if (tok == '=') {
17740 int n;
17741 next();
17742 n = asm_int_expr(s1);
17743 asm_new_label1(s1, opcode, 0, SHN_ABS, n);
17744 goto redo;
17745 } else {
17746 asm_opcode(s1, opcode);
17747 }
17748 }
17749
17750 if (tok != ';' && tok != TOK_LINEFEED){
17751 expect("end of line");
17752 }
17753 parse_flags &= ~PARSE_FLAG_LINEFEED;
17754 ();
17755 }
17756
17757 asm_free_labels(s1);
17758
17759 return 0;
17760 }
17761
17762
17763 static int tcc_assemble(TCCState *s1, int do_preprocess)
17764 {
17765 Sym *define_start;
17766 int ret;
17767
17768 preprocess_init(s1);
17769
17770
17771 = text_section;
17772 ind = cur_text_section->data_offset;
17773
17774 define_start = define_stack;
17775
17776 ret = tcc_assemble_internal(s1, do_preprocess);
17777
17778 cur_text_section->data_offset = ind;
17779
17780 free_defines(define_start);
17781
17782 return ret;
17783 }
17784
17785
17786
17787
17788
17789
17790
17791 static void tcc_assemble_inline(TCCState *s1, char *str, int len)
17792 {
17793 BufferedFile *bf, *saved_file;
17794 int saved_parse_flags, *saved_macro_ptr;
17795
17796 bf = tcc_malloc(sizeof(BufferedFile));
17797 memset(bf, 0, sizeof(BufferedFile));
17798 bf->fd = -1;
17799 bf->buf_ptr = str;
17800 bf->buf_end = str + len;
17801 str[len] = CH_EOB;
17802
17803
17804 (bf->filename, sizeof(bf->filename), file->filename);
17805 bf->line_num = file->line_num;
17806 saved_file = file;
17807 file = bf;
17808 saved_parse_flags = parse_flags;
17809 saved_macro_ptr = macro_ptr;
17810 macro_ptr = NULL;
17811
17812 tcc_assemble_internal(s1, 0);
17813
17814 parse_flags = saved_parse_flags;
17815 macro_ptr = saved_macro_ptr;
17816 file = saved_file;
17817 tcc_free(bf);
17818 }
17819
17820
17821
17822
17823 static int find_constraint(ASMOperand *operands, int nb_operands,
17824 const char *name, const char **pp)
17825 {
17826 int index;
17827 TokenSym *ts;
17828 const char *p;
17829
17830 if (isnum(*name)) {
17831 index = 0;
17832 while (isnum(*name)) {
17833 index = (index * 10) + (*name) - '0';
17834 name++;
17835 }
17836 if ((unsigned)index >= nb_operands)
17837 index = -1;
17838 } else if (*name == '[') {
17839 name++;
17840 p = strchr(name, ']');
17841 if (p) {
17842 ts = tok_alloc(name, p - name);
17843 for(index = 0; index < nb_operands; index++) {
17844 if (operands[index].id == ts->tok)
17845 goto found;
17846 }
17847 index = -1;
17848 found:
17849 name = p + 1;
17850 } else {
17851 index = -1;
17852 }
17853 } else {
17854 index = -1;
17855 }
17856 if (pp)
17857 *pp = name;
17858 return index;
17859 }
17860
17861 static void subst_asm_operands(ASMOperand *operands, int nb_operands,
17862 int nb_outputs,
17863 CString *out_str, CString *in_str)
17864 {
17865 int c, index, modifier;
17866 const char *str;
17867 ASMOperand *op;
17868 SValue sv;
17869
17870 cstr_new(out_str);
17871 str = in_str->data;
17872 for(;;) {
17873 c = *str++;
17874 if (c == '%') {
17875 if (*str == '%') {
17876 str++;
17877 goto add_char;
17878 }
17879 modifier = 0;
17880 if (*str == 'c' || *str == 'n' ||
17881 *str == 'b' || *str == 'w' || *str == 'h')
17882 modifier = *str++;
17883 index = find_constraint(operands, nb_operands, str, &str);
17884 if (index < 0)
17885 error("invalid operand reference after %%");
17886 op = &operands[index];
17887 sv = *op->vt;
17888 if (op->reg >= 0) {
17889 sv.r = op->reg;
17890 if ((op->vt->r & VT_VALMASK) == VT_LLOCAL)
17891 sv.r |= VT_LVAL;
17892 }
17893 subst_asm_operand(out_str, &sv, modifier);
17894 } else {
17895 add_char:
17896 cstr_ccat(out_str, c);
17897 if (c == '\0')
17898 break;
17899 }
17900 }
17901 }
17902
17903
17904 static void parse_asm_operands(ASMOperand *operands, int *nb_operands_ptr,
17905 int is_output)
17906 {
17907 ASMOperand *op;
17908 int nb_operands;
17909
17910 if (tok != ':') {
17911 nb_operands = *nb_operands_ptr;
17912 for(;;) {
17913 if (nb_operands >= MAX_ASM_OPERANDS)
17914 error("too many asm operands");
17915 op = &operands[nb_operands++];
17916 op->id = 0;
17917 if (tok == '[') {
17918 next();
17919 if (tok < TOK_IDENT)
17920 expect("identifier");
17921 op->id = tok;
17922 next();
17923 skip(']');
17924 }
17925 if (tok != TOK_STR)
17926 expect("string constant");
17927 op->constraint = tcc_malloc(tokc.cstr->size);
17928 strcpy(op->constraint, tokc.cstr->data);
17929 next();
17930 skip('(');
17931 gexpr();
17932 if (is_output) {
17933 test_lvalue();
17934 } else {
17935
17936
17937
17938
17939 if ((vtop->r & VT_LVAL) &&
17940 ((vtop->r & VT_VALMASK) == VT_LLOCAL ||
17941 (vtop->r & VT_VALMASK) < VT_CONST) &&
17942 !strchr(op->constraint, 'm')) {
17943 gv(RC_INT);
17944 }
17945 }
17946 op->vt = vtop;
17947 skip(')');
17948 if (tok == ',') {
17949 next();
17950 } else {
17951 break;
17952 }
17953 }
17954 *nb_operands_ptr = nb_operands;
17955 }
17956 }
17957
17958 static void parse_asm_str(CString *astr)
17959 {
17960 skip('(');
17961
17962 if (tok != TOK_STR)
17963 expect("string constant");
17964 cstr_new(astr);
17965 while (tok == TOK_STR) {
17966
17967 (astr, tokc.cstr->data);
17968 next();
17969 }
17970 cstr_ccat(astr, '\0');
17971 }
17972
17973
17974 static void asm_instr(void)
17975 {
17976 CString astr, astr1;
17977 ASMOperand operands[MAX_ASM_OPERANDS];
17978 int nb_inputs __attribute__((unused));
17979 int nb_outputs, nb_operands, i, must_subst, out_reg;
17980 uint8_t clobber_regs[NB_ASM_REGS];
17981
17982 next();
17983
17984
17985 if (tok == TOK_VOLATILE1 || tok == TOK_VOLATILE2 || tok == TOK_VOLATILE3) {
17986 next();
17987 }
17988 parse_asm_str(&astr);
17989 nb_operands = 0;
17990 nb_outputs = 0;
17991 must_subst = 0;
17992 memset(clobber_regs, 0, sizeof(clobber_regs));
17993 if (tok == ':') {
17994 next();
17995 must_subst = 1;
17996
17997 (operands, &nb_operands, 1);
17998 nb_outputs = nb_operands;
17999 if (tok == ':') {
18000 next();
18001
18002 (operands, &nb_operands, 0);
18003 if (tok == ':') {
18004
18005
18006 ();
18007 for(;;) {
18008 if (tok != TOK_STR)
18009 expect("string constant");
18010 asm_clobber(clobber_regs, tokc.cstr->data);
18011 next();
18012 if (tok == ',') {
18013 next();
18014 } else {
18015 break;
18016 }
18017 }
18018 }
18019 }
18020 }
18021 skip(')');
18022
18023
18024 if (tok != ';')
18025 expect("';'");
18026 nb_inputs = nb_operands - nb_outputs;
18027
18028
18029 (0);
18030
18031
18032 (operands, nb_operands, nb_outputs,
18033 clobber_regs, &out_reg);
18034
18035
18036
18037 #ifdef ASM_DEBUG
18038 printf("asm: \"%s\"\n", (char *)astr.data);
18039 #endif
18040 if (must_subst) {
18041 subst_asm_operands(operands, nb_operands, nb_outputs, &astr1, &astr);
18042 cstr_free(&astr);
18043 } else {
18044 astr1 = astr;
18045 }
18046 #ifdef ASM_DEBUG
18047 printf("subst_asm: \"%s\"\n", (char *)astr1.data);
18048 #endif
18049
18050
18051 (operands, nb_operands, nb_outputs, 0,
18052 clobber_regs, out_reg);
18053
18054
18055 (tcc_state, astr1.data, astr1.size - 1);
18056
18057
18058 ();
18059
18060
18061 (operands, nb_operands, nb_outputs, 1,
18062 clobber_regs, out_reg);
18063
18064
18065 for(i=0;i<nb_operands;i++) {
18066 ASMOperand *op;
18067 op = &operands[i];
18068 tcc_free(op->constraint);
18069 vpop();
18070 }
18071 cstr_free(&astr1);
18072 }
18073
18074 static void asm_global_instr(void)
18075 {
18076 CString astr;
18077
18078 next();
18079 parse_asm_str(&astr);
18080 skip(')');
18081
18082
18083 if (tok != ';')
18084 expect("';'");
18085
18086 #ifdef ASM_DEBUG
18087 printf("asm_global: \"%s\"\n", (char *)astr.data);
18088 #endif
18089 cur_text_section = text_section;
18090 ind = cur_text_section->data_offset;
18091
18092
18093 (tcc_state, astr.data, astr.size - 1);
18094
18095 cur_text_section->data_offset = ind;
18096
18097
18098 ();
18099
18100 cstr_free(&astr);
18101 }
18102
18103
18104 #else
18105 static void asm_instr(void)
18106 {
18107 error("inline asm() not supported");
18108 }
18109 static void asm_global_instr(void)
18110 {
18111 error("inline asm() not supported");
18112 }
18113 #endif
18114
18115
18116
18117
18118
18119
18120
18121
18122
18123
18124
18125
18126
18127
18128
18129
18130
18131
18132
18133
18134
18135
18136
18137
18138 static int put_elf_str(Section *s, const char *sym)
18139 {
18140 int offset, len;
18141 char *ptr;
18142
18143 len = strlen(sym) + 1;
18144 offset = s->data_offset;
18145 ptr = section_ptr_add(s, len);
18146 memcpy(ptr, sym, len);
18147 return offset;
18148 }
18149
18150
18151 static unsigned long elf_hash(const unsigned char *name)
18152 {
18153 unsigned long h = 0, g;
18154
18155 while (*name) {
18156 h = (h << 4) + *name++;
18157 g = h & 0xf0000000;
18158 if (g)
18159 h ^= g >> 24;
18160 h &= ~g;
18161 }
18162 return h;
18163 }
18164
18165
18166
18167 static void rebuild_hash(Section *s, unsigned int nb_buckets)
18168 {
18169 Elf32_Sym *sym;
18170 int *ptr, *hash, nb_syms, sym_index, h;
18171 char *strtab;
18172
18173 strtab = s->link->data;
18174 nb_syms = s->data_offset / sizeof(Elf32_Sym);
18175
18176 s->hash->data_offset = 0;
18177 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
18178 ptr[0] = nb_buckets;
18179 ptr[1] = nb_syms;
18180 ptr += 2;
18181 hash = ptr;
18182 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
18183 ptr += nb_buckets + 1;
18184
18185 sym = (Elf32_Sym *)s->data + 1;
18186 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
18187 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
18188 h = elf_hash(strtab + sym->st_name) % nb_buckets;
18189 *ptr = hash[h];
18190 hash[h] = sym_index;
18191 } else {
18192 *ptr = 0;
18193 }
18194 ptr++;
18195 sym++;
18196 }
18197 }
18198
18199
18200 static int put_elf_sym(Section *s,
18201 unsigned long value, unsigned long size,
18202 int info, int other, int shndx, const char *name)
18203 {
18204 int name_offset, sym_index;
18205 int nbuckets, h;
18206 Elf32_Sym *sym;
18207 Section *hs;
18208
18209 sym = section_ptr_add(s, sizeof(Elf32_Sym));
18210 if (name)
18211 name_offset = put_elf_str(s->link, name);
18212 else
18213 name_offset = 0;
18214
18215 ->st_name = name_offset;
18216 sym->st_value = value;
18217 sym->st_size = size;
18218 sym->st_info = info;
18219 sym->st_other = other;
18220 sym->st_shndx = shndx;
18221 sym_index = sym - (Elf32_Sym *)s->data;
18222 hs = s->hash;
18223 if (hs) {
18224 int *ptr, *base;
18225 ptr = section_ptr_add(hs, sizeof(int));
18226 base = (int *)hs->data;
18227
18228 if (ELF32_ST_BIND(info) != STB_LOCAL) {
18229
18230 = base[0];
18231 h = elf_hash(name) % nbuckets;
18232 *ptr = base[2 + h];
18233 base[2 + h] = sym_index;
18234 base[1]++;
18235
18236 ->nb_hashed_syms++;
18237 if (hs->nb_hashed_syms > 2 * nbuckets) {
18238 rebuild_hash(s, 2 * nbuckets);
18239 }
18240 } else {
18241 *ptr = 0;
18242 base[1]++;
18243 }
18244 }
18245 return sym_index;
18246 }
18247
18248
18249
18250 static int find_elf_sym(Section *s, const char *name)
18251 {
18252 Elf32_Sym *sym;
18253 Section *hs;
18254 int nbuckets, sym_index, h;
18255 const char *name1;
18256
18257 hs = s->hash;
18258 if (!hs)
18259 return 0;
18260 nbuckets = ((int *)hs->data)[0];
18261 h = elf_hash(name) % nbuckets;
18262 sym_index = ((int *)hs->data)[2 + h];
18263 while (sym_index != 0) {
18264 sym = &((Elf32_Sym *)s->data)[sym_index];
18265 name1 = s->link->data + sym->st_name;
18266 if (!strcmp(name, name1))
18267 return sym_index;
18268 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
18269 }
18270 return 0;
18271 }
18272
18273
18274 int tcc_get_symbol(TCCState *s, unsigned long *pval, const char *name)
18275 {
18276 int sym_index;
18277 Elf32_Sym *sym;
18278
18279 sym_index = find_elf_sym(symtab_section, name);
18280 if (!sym_index)
18281 return -1;
18282 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
18283 *pval = sym->st_value;
18284 return 0;
18285 }
18286
18287 void *tcc_get_symbol_err(TCCState *s, const char *name)
18288 {
18289 unsigned long val;
18290 if (tcc_get_symbol(s, &val, name) < 0)
18291 error("%s not defined", name);
18292 return (void *)val;
18293 }
18294
18295
18296
18297 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
18298 int info, int other, int sh_num, const char *name)
18299 {
18300 Elf32_Sym *esym;
18301 int sym_bind, sym_index, sym_type, esym_bind;
18302
18303 sym_bind = ELF32_ST_BIND(info);
18304 sym_type = ELF32_ST_TYPE(info);
18305
18306 if (sym_bind != STB_LOCAL) {
18307
18308 = find_elf_sym(s, name);
18309 if (!sym_index)
18310 goto do_def;
18311 esym = &((Elf32_Sym *)s->data)[sym_index];
18312 if (esym->st_shndx != SHN_UNDEF) {
18313 esym_bind = ELF32_ST_BIND(esym->st_info);
18314 if (sh_num == SHN_UNDEF) {
18315
18316
18317 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
18318
18319 goto do_patch;
18320 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
18321
18322 } else {
18323 #if 0
18324 printf("new_bind=%d new_shndx=%d last_bind=%d old_shndx=%d\n",
18325 sym_bind, sh_num, esym_bind, esym->st_shndx);
18326 #endif
18327
18328 if (s != tcc_state->dynsymtab_section)
18329 error_noabort("'%s' defined twice", name);
18330 }
18331 } else {
18332 do_patch:
18333 esym->st_info = ELF32_ST_INFO(sym_bind, sym_type);
18334 esym->st_shndx = sh_num;
18335 esym->st_value = value;
18336 esym->st_size = size;
18337 esym->st_other = other;
18338 }
18339 } else {
18340 do_def:
18341 sym_index = put_elf_sym(s, value, size,
18342 ELF32_ST_INFO(sym_bind, sym_type), other,
18343 sh_num, name);
18344 }
18345 return sym_index;
18346 }
18347
18348
18349 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
18350 int type, int symbol)
18351 {
18352 char buf[256];
18353 Section *sr;
18354 Elf32_Rel *rel;
18355
18356 sr = s->reloc;
18357 if (!sr) {
18358
18359 (buf, sizeof(buf), ".rel%s", s->name);
18360
18361
18362 = new_section(tcc_state, buf, SHT_REL, symtab->sh_flags);
18363 sr->sh_entsize = sizeof(Elf32_Rel);
18364 sr->link = symtab;
18365 sr->sh_info = s->sh_num;
18366 s->reloc = sr;
18367 }
18368 rel = section_ptr_add(sr, sizeof(Elf32_Rel));
18369 rel->r_offset = offset;
18370 rel->r_info = ELF32_R_INFO(symbol, type);
18371 }
18372
18373
18374
18375 typedef struct {
18376 unsigned long n_strx;
18377 unsigned char n_type;
18378 unsigned char n_other;
18379 unsigned short n_desc;
18380 unsigned long n_value;
18381 } Stab_Sym;
18382
18383 static void put_stabs(const char *str, int type, int other, int desc,
18384 unsigned long value)
18385 {
18386 Stab_Sym *sym;
18387
18388 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
18389 if (str) {
18390 sym->n_strx = put_elf_str(stabstr_section, str);
18391 } else {
18392 sym->n_strx = 0;
18393 }
18394 sym->n_type = type;
18395 sym->n_other = other;
18396 sym->n_desc = desc;
18397 sym->n_value = value;
18398 }
18399
18400 static void put_stabs_r(const char *str, int type, int other, int desc,
18401 unsigned long value, Section *sec, int sym_index)
18402 {
18403 put_stabs(str, type, other, desc, value);
18404 put_elf_reloc(symtab_section, stab_section,
18405 stab_section->data_offset - sizeof(unsigned long),
18406 R_DATA_32, sym_index);
18407 }
18408
18409 static void put_stabn(int type, int other, int desc, int value)
18410 {
18411 put_stabs(NULL, type, other, desc, value);
18412 }
18413
18414 static void put_stabd(int type, int other, int desc)
18415 {
18416 put_stabs(NULL, type, other, desc, 0);
18417 }
18418
18419
18420
18421
18422
18423 static void sort_syms(TCCState *s1, Section *s)
18424 {
18425 int *old_to_new_syms;
18426 Elf32_Sym *new_syms;
18427 int nb_syms, i;
18428 Elf32_Sym *p, *q;
18429 Elf32_Rel *rel, *rel_end;
18430 Section *sr;
18431 int type, sym_index;
18432
18433 nb_syms = s->data_offset / sizeof(Elf32_Sym);
18434 new_syms = tcc_malloc(nb_syms * sizeof(Elf32_Sym));
18435 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
18436
18437
18438 = (Elf32_Sym *)s->data;
18439 q = new_syms;
18440 for(i = 0; i < nb_syms; i++) {
18441 if (ELF32_ST_BIND(p->st_info) == STB_LOCAL) {
18442 old_to_new_syms[i] = q - new_syms;
18443 *q++ = *p;
18444 }
18445 p++;
18446 }
18447
18448 ->sh_info = q - new_syms;
18449
18450
18451 = (Elf32_Sym *)s->data;
18452 for(i = 0; i < nb_syms; i++) {
18453 if (ELF32_ST_BIND(p->st_info) != STB_LOCAL) {
18454 old_to_new_syms[i] = q - new_syms;
18455 *q++ = *p;
18456 }
18457 p++;
18458 }
18459
18460
18461 (s->data, new_syms, nb_syms * sizeof(Elf32_Sym));
18462 tcc_free(new_syms);
18463
18464
18465 for(i = 1; i < s1->nb_sections; i++) {
18466 sr = s1->sections[i];
18467 if (sr->sh_type == SHT_REL && sr->link == s) {
18468 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
18469 for(rel = (Elf32_Rel *)sr->data;
18470 rel < rel_end;
18471 rel++) {
18472 sym_index = ELF32_R_SYM(rel->r_info);
18473 type = ELF32_R_TYPE(rel->r_info);
18474 sym_index = old_to_new_syms[sym_index];
18475 rel->r_info = ELF32_R_INFO(sym_index, type);
18476 }
18477 }
18478 }
18479
18480 tcc_free(old_to_new_syms);
18481 }
18482
18483
18484 static void relocate_common_syms(void)
18485 {
18486 Elf32_Sym *sym, *sym_end;
18487 unsigned long offset, align;
18488
18489 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
18490 for(sym = (Elf32_Sym *)symtab_section->data + 1;
18491 sym < sym_end;
18492 sym++) {
18493 if (sym->st_shndx == SHN_COMMON) {
18494
18495 = sym->st_value;
18496 offset = bss_section->data_offset;
18497 offset = (offset + align - 1) & -align;
18498 sym->st_value = offset;
18499 sym->st_shndx = bss_section->sh_num;
18500 offset += sym->st_size;
18501 bss_section->data_offset = offset;
18502 }
18503 }
18504 }
18505
18506
18507
18508 static void relocate_syms(TCCState *s1, int do_resolve)
18509 {
18510 Elf32_Sym *sym, *esym, *sym_end;
18511 int sym_bind, sh_num, sym_index;
18512 const char *name;
18513 unsigned long addr;
18514
18515 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
18516 for(sym = (Elf32_Sym *)symtab_section->data + 1;
18517 sym < sym_end;
18518 sym++) {
18519 sh_num = sym->st_shndx;
18520 if (sh_num == SHN_UNDEF) {
18521 name = strtab_section->data + sym->st_name;
18522 if (do_resolve) {
18523 name = symtab_section->link->data + sym->st_name;
18524 addr = (unsigned long)resolve_sym(s1, name, ELF32_ST_TYPE(sym->st_info));
18525 if (addr) {
18526 sym->st_value = addr;
18527 goto found;
18528 }
18529 } else if (s1->dynsym) {
18530
18531 = find_elf_sym(s1->dynsym, name);
18532 if (sym_index) {
18533 esym = &((Elf32_Sym *)s1->dynsym->data)[sym_index];
18534 sym->st_value = esym->st_value;
18535 goto found;
18536 }
18537 }
18538
18539
18540 if (!strcmp(name, "_fp_hw"))
18541 goto found;
18542
18543
18544 = ELF32_ST_BIND(sym->st_info);
18545 if (sym_bind == STB_WEAK) {
18546 sym->st_value = 0;
18547 } else {
18548 error_noabort("undefined symbol '%s'", name);
18549 }
18550 } else if (sh_num < SHN_LORESERVE) {
18551
18552 ->st_value += s1->sections[sym->st_shndx]->sh_addr;
18553 }
18554 found: ;
18555 }
18556 }
18557
18558
18559 static void relocate_section(TCCState *s1, Section *s)
18560 {
18561 Section *sr;
18562 Elf32_Rel *rel, *rel_end, *qrel;
18563 Elf32_Sym *sym;
18564 int type, sym_index;
18565 unsigned char *ptr;
18566 unsigned long val, addr;
18567 #if defined(TCC_TARGET_I386)
18568 int esym_index;
18569 #endif
18570
18571 sr = s->reloc;
18572 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
18573 qrel = (Elf32_Rel *)sr->data;
18574 for(rel = qrel;
18575 rel < rel_end;
18576 rel++) {
18577 ptr = s->data + rel->r_offset;
18578
18579 sym_index = ELF32_R_SYM(rel->r_info);
18580 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
18581 val = sym->st_value;
18582 type = ELF32_R_TYPE(rel->r_info);
18583 addr = s->sh_addr + rel->r_offset;
18584
18585
18586 switch(type) {
18587 #if defined(TCC_TARGET_I386)
18588 case R_386_32:
18589 if (s1->output_type == TCC_OUTPUT_DLL) {
18590 esym_index = s1->symtab_to_dynsym[sym_index];
18591 qrel->r_offset = rel->r_offset;
18592 if (esym_index) {
18593 qrel->r_info = ELF32_R_INFO(esym_index, R_386_32);
18594 qrel++;
18595 break;
18596 } else {
18597 qrel->r_info = ELF32_R_INFO(0, R_386_RELATIVE);
18598 qrel++;
18599 }
18600 }
18601 *(int *)ptr += val;
18602 break;
18603 case R_386_PC32:
18604 if (s1->output_type == TCC_OUTPUT_DLL) {
18605
18606 = s1->symtab_to_dynsym[sym_index];
18607 if (esym_index) {
18608 qrel->r_offset = rel->r_offset;
18609 qrel->r_info = ELF32_R_INFO(esym_index, R_386_PC32);
18610 qrel++;
18611 break;
18612 }
18613 }
18614 *(int *)ptr += val - addr;
18615 break;
18616 case R_386_PLT32:
18617 *(int *)ptr += val - addr;
18618 break;
18619 case R_386_GLOB_DAT:
18620 case R_386_JMP_SLOT:
18621 *(int *)ptr = val;
18622 break;
18623 case R_386_GOTPC:
18624 *(int *)ptr += s1->got->sh_addr - addr;
18625 break;
18626 case R_386_GOTOFF:
18627 *(int *)ptr += val - s1->got->sh_addr;
18628 break;
18629 case R_386_GOT32:
18630
18631 *(int *)ptr += s1->got_offsets[sym_index];
18632 break;
18633 #elif defined(TCC_TARGET_ARM)
18634 case R_ARM_PC24:
18635 case R_ARM_PLT32:
18636 {
18637 int x;
18638 x = (*(int *)ptr)&0xffffff;
18639 (*(int *)ptr) &= 0xff000000;
18640 if (x & 0x800000)
18641 x -= 0x1000000;
18642 x *= 4;
18643 x += val - addr;
18644 if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
18645 error("can't relocate value at %x",addr);
18646 x >>= 2;
18647 x &= 0xffffff;
18648 (*(int *)ptr) |= x;
18649 }
18650 break;
18651 case R_ARM_ABS32:
18652 *(int *)ptr += val;
18653 break;
18654 case R_ARM_GOTPC:
18655 *(int *)ptr += s1->got->sh_addr - addr;
18656 break;
18657 case R_ARM_GOT32:
18658
18659 *(int *)ptr += s1->got_offsets[sym_index];
18660 break;
18661 case R_ARM_COPY:
18662 break;
18663 default:
18664 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
18665 type,addr,(unsigned int )ptr,val);
18666 break;
18667 #elif defined(TCC_TARGET_C67)
18668 case R_C60_32:
18669 *(int *)ptr += val;
18670 break;
18671 case R_C60LO16:
18672 {
18673 uint32_t orig;
18674
18675
18676
18677
18678 orig = ((*(int *)(ptr )) >> 7) & 0xffff;
18679 orig |= (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
18680
18681
18682
18683 *(int *) ptr = (*(int *) ptr & (~(0xffff << 7)) ) | (((val+orig) & 0xffff) << 7);
18684 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
18685 }
18686 break;
18687 case R_C60HI16:
18688 break;
18689 default:
18690 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
18691 type,addr,(unsigned int )ptr,val);
18692 break;
18693 #else
18694 #error unsupported processor
18695 #endif
18696 }
18697 }
18698
18699 if (sr->sh_flags & SHF_ALLOC)
18700 sr->link = s1->dynsym;
18701 }
18702
18703
18704 static void relocate_rel(TCCState *s1, Section *sr)
18705 {
18706 Section *s;
18707 Elf32_Rel *rel, *rel_end;
18708
18709 s = s1->sections[sr->sh_info];
18710 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
18711 for(rel = (Elf32_Rel *)sr->data;
18712 rel < rel_end;
18713 rel++) {
18714 rel->r_offset += s->sh_addr;
18715 }
18716 }
18717
18718
18719
18720 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
18721 {
18722 Elf32_Rel *rel, *rel_end;
18723 int sym_index, esym_index, type, count;
18724
18725 count = 0;
18726 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
18727 for(rel = (Elf32_Rel *)sr->data; rel < rel_end; rel++) {
18728 sym_index = ELF32_R_SYM(rel->r_info);
18729 type = ELF32_R_TYPE(rel->r_info);
18730 switch(type) {
18731 case R_386_32:
18732 count++;
18733 break;
18734 case R_386_PC32:
18735 esym_index = s1->symtab_to_dynsym[sym_index];
18736 if (esym_index)
18737 count++;
18738 break;
18739 default:
18740 break;
18741 }
18742 }
18743 if (count) {
18744
18745 ->sh_flags |= SHF_ALLOC;
18746 sr->sh_size = count * sizeof(Elf32_Rel);
18747 }
18748 return count;
18749 }
18750
18751 static void put_got_offset(TCCState *s1, int index, unsigned long val)
18752 {
18753 int n;
18754 unsigned long *tab;
18755
18756 if (index >= s1->nb_got_offsets) {
18757
18758 = 1;
18759 while (index >= n)
18760 n *= 2;
18761 tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long));
18762 if (!tab)
18763 error("memory full");
18764 s1->got_offsets = tab;
18765 memset(s1->got_offsets + s1->nb_got_offsets, 0,
18766 (n - s1->nb_got_offsets) * sizeof(unsigned long));
18767 s1->nb_got_offsets = n;
18768 }
18769 s1->got_offsets[index] = val;
18770 }
18771
18772
18773 static void put32(unsigned char *p, uint32_t val)
18774 {
18775 p[0] = val;
18776 p[1] = val >> 8;
18777 p[2] = val >> 16;
18778 p[3] = val >> 24;
18779 }
18780
18781 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM)
18782 static uint32_t get32(unsigned char *p)
18783 {
18784 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
18785 }
18786 #endif
18787
18788 static void build_got(TCCState *s1)
18789 {
18790 unsigned char *ptr;
18791
18792
18793 ->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
18794 s1->got->sh_entsize = 4;
18795 add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT),
18796 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
18797 ptr = section_ptr_add(s1->got, 3 * sizeof(int));
18798
18799 (ptr, 0);
18800
18801 (ptr + 4, 0);
18802 put32(ptr + 8, 0);
18803 }
18804
18805
18806
18807 static void put_got_entry(TCCState *s1,
18808 int reloc_type, unsigned long size, int info,
18809 int sym_index)
18810 {
18811 int index;
18812 const char *name;
18813 Elf32_Sym *sym;
18814 unsigned long offset;
18815 int *ptr;
18816
18817 if (!s1->got)
18818 build_got(s1);
18819
18820
18821 if (sym_index < s1->nb_got_offsets &&
18822 s1->got_offsets[sym_index] != 0)
18823 return;
18824
18825 put_got_offset(s1, sym_index, s1->got->data_offset);
18826
18827 if (s1->dynsym) {
18828 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
18829 name = symtab_section->link->data + sym->st_name;
18830 offset = sym->st_value;
18831 #ifdef TCC_TARGET_I386
18832 if (reloc_type == R_386_JMP_SLOT) {
18833 Section *plt;
18834 uint8_t *p;
18835 int modrm;
18836
18837
18838 if (s1->output_type == TCC_OUTPUT_DLL)
18839 modrm = 0xa3;
18840 else
18841 modrm = 0x25;
18842
18843
18844 = s1->plt;
18845 if (plt->data_offset == 0) {
18846
18847 = section_ptr_add(plt, 16);
18848 p[0] = 0xff;
18849 [1] = modrm + 0x10;
18850 put32(p + 2, 4);
18851 p[6] = 0xff;
18852 [7] = modrm;
18853 put32(p + 8, 8);
18854 }
18855
18856 p = section_ptr_add(plt, 16);
18857 p[0] = 0xff;
18858 [1] = modrm;
18859 put32(p + 2, s1->got->data_offset);
18860 p[6] = 0x68;
18861 (p + 7, (plt->data_offset - 32) >> 1);
18862 p[11] = 0xe9;
18863 (p + 12, -(plt->data_offset));
18864
18865
18866
18867 if (s1->output_type == TCC_OUTPUT_EXE)
18868 offset = plt->data_offset - 16;
18869 }
18870 #elif defined(TCC_TARGET_ARM)
18871 if (reloc_type == R_ARM_JUMP_SLOT) {
18872 Section *plt;
18873 uint8_t *p;
18874
18875
18876 if (s1->output_type == TCC_OUTPUT_DLL)
18877 error("DLLs unimplemented!");
18878
18879
18880 plt = s1->plt;
18881 if (plt->data_offset == 0) {
18882
18883 p = section_ptr_add(plt, 16);
18884 put32(p , 0xe52de004);
18885 put32(p + 4, 0xe59fe010);
18886 put32(p + 8, 0xe08fe00e);
18887 put32(p + 12, 0xe5bef008);
18888 }
18889
18890 p = section_ptr_add(plt, 16);
18891 put32(p , 0xe59fc004);
18892 put32(p+4, 0xe08fc00c);
18893 put32(p+8, 0xe59cf000);
18894 put32(p+12, s1->got->data_offset);
18895
18896
18897
18898 if (s1->output_type == TCC_OUTPUT_EXE)
18899 offset = plt->data_offset - 16;
18900 }
18901 #elif defined(TCC_TARGET_C67)
18902 error("C67 got not implemented");
18903 #else
18904 #error unsupported CPU
18905 #endif
18906 index = put_elf_sym(s1->dynsym, offset,
18907 size, info, 0, sym->st_shndx, name);
18908
18909 (s1->dynsym, s1->got,
18910 s1->got->data_offset,
18911 reloc_type, index);
18912 }
18913 ptr = section_ptr_add(s1->got, sizeof(int));
18914 *ptr = 0;
18915 }
18916
18917
18918 static void build_got_entries(TCCState *s1)
18919 {
18920 Section *s, *symtab __attribute__((unused));
18921 Elf32_Rel *rel, *rel_end;
18922 Elf32_Sym *sym;
18923 int i, type, reloc_type, sym_index;
18924
18925 for(i = 1; i < s1->nb_sections; i++) {
18926 s = s1->sections[i];
18927 if (s->sh_type != SHT_REL)
18928 continue;
18929
18930 if (s->link != symtab_section)
18931 continue;
18932 symtab = s->link;
18933 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
18934 for(rel = (Elf32_Rel *)s->data;
18935 rel < rel_end;
18936 rel++) {
18937 type = ELF32_R_TYPE(rel->r_info);
18938 switch(type) {
18939 #if defined(TCC_TARGET_I386)
18940 case R_386_GOT32:
18941 case R_386_GOTOFF:
18942 case R_386_GOTPC:
18943 case R_386_PLT32:
18944 if (!s1->got)
18945 build_got(s1);
18946 if (type == R_386_GOT32 || type == R_386_PLT32) {
18947 sym_index = ELF32_R_SYM(rel->r_info);
18948 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
18949
18950 if (type == R_386_GOT32)
18951 reloc_type = R_386_GLOB_DAT;
18952 else
18953 reloc_type = R_386_JMP_SLOT;
18954 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
18955 sym_index);
18956 }
18957 break;
18958 #elif defined(TCC_TARGET_ARM)
18959 case R_ARM_GOT32:
18960 case R_ARM_GOTOFF:
18961 case R_ARM_GOTPC:
18962 case R_ARM_PLT32:
18963 if (!s1->got)
18964 build_got(s1);
18965 if (type == R_ARM_GOT32 || type == R_ARM_PLT32) {
18966 sym_index = ELF32_R_SYM(rel->r_info);
18967 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
18968
18969 if (type == R_ARM_GOT32)
18970 reloc_type = R_ARM_GLOB_DAT;
18971 else
18972 reloc_type = R_ARM_JUMP_SLOT;
18973 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
18974 sym_index);
18975 }
18976 break;
18977 #elif defined(TCC_TARGET_C67)
18978 case R_C60_GOT32:
18979 case R_C60_GOTOFF:
18980 case R_C60_GOTPC:
18981 case R_C60_PLT32:
18982 if (!s1->got)
18983 build_got(s1);
18984 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
18985 sym_index = ELF32_R_SYM(rel->r_info);
18986 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
18987
18988 if (type == R_C60_GOT32)
18989 reloc_type = R_C60_GLOB_DAT;
18990 else
18991 reloc_type = R_C60_JMP_SLOT;
18992 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
18993 sym_index);
18994 }
18995 break;
18996 #else
18997 #error unsupported CPU
18998 #endif
18999 default:
19000 break;
19001 }
19002 }
19003 }
19004 }
19005
19006 static Section *new_symtab(TCCState *s1,
19007 const char *symtab_name, int sh_type, int sh_flags,
19008 const char *strtab_name,
19009 const char *hash_name, int hash_sh_flags)
19010 {
19011 Section *symtab, *strtab, *hash;
19012 int *ptr, nb_buckets;
19013
19014 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
19015 symtab->sh_entsize = sizeof(Elf32_Sym);
19016 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
19017 put_elf_str(strtab, "");
19018 symtab->link = strtab;
19019 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
19020
19021 nb_buckets = 1;
19022
19023 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
19024 hash->sh_entsize = sizeof(int);
19025 symtab->hash = hash;
19026 hash->link = symtab;
19027
19028 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
19029 ptr[0] = nb_buckets;
19030 ptr[1] = 1;
19031 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
19032 return symtab;
19033 }
19034
19035
19036 static void put_dt(Section *dynamic, int dt, unsigned long val)
19037 {
19038 Elf32_Dyn *dyn;
19039 dyn = section_ptr_add(dynamic, sizeof(Elf32_Dyn));
19040 dyn->d_tag = dt;
19041 dyn->d_un.d_val = val;
19042 }
19043
19044 static void add_init_array_defines(TCCState *s1, const char *section_name)
19045 {
19046 Section *s;
19047 long end_offset;
19048 char sym_start[1024];
19049 char sym_end[1024];
19050
19051 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
19052 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
19053
19054 s = find_section(s1, section_name);
19055 if (!s) {
19056 end_offset = 0;
19057 s = data_section;
19058 } else {
19059 end_offset = s->data_offset;
19060 }
19061
19062 add_elf_sym(symtab_section,
19063 0, 0,
19064 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19065 s->sh_num, sym_start);
19066 add_elf_sym(symtab_section,
19067 end_offset, 0,
19068 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19069 s->sh_num, sym_end);
19070 }
19071
19072
19073 static void tcc_add_runtime(TCCState *s1)
19074 {
19075 char buf[1024];
19076
19077 #ifdef CONFIG_TCC_BCHECK
19078 if (do_bounds_check) {
19079 unsigned long *ptr;
19080 Section *init_section;
19081 unsigned char *pinit;
19082 int sym_index;
19083
19084
19085 = section_ptr_add(bounds_section, sizeof(unsigned long));
19086 *ptr = 0;
19087 add_elf_sym(symtab_section, 0, 0,
19088 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19089 bounds_section->sh_num, "__bounds_start");
19090
19091 (buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
19092 tcc_add_file(s1, buf);
19093 #ifdef TCC_TARGET_I386
19094 if (s1->output_type != TCC_OUTPUT_MEMORY) {
19095
19096 = find_section(s1, ".init");
19097 pinit = section_ptr_add(init_section, 5);
19098 pinit[0] = 0xe8;
19099 put32(pinit + 1, -4);
19100 sym_index = find_elf_sym(symtab_section, "__bound_init");
19101 put_elf_reloc(symtab_section, init_section,
19102 init_section->data_offset - 4, R_386_PC32, sym_index);
19103 }
19104 #endif
19105 }
19106 #endif
19107
19108 if (!s1->nostdlib) {
19109 tcc_add_library(s1, "c");
19110
19111 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");
19112 tcc_add_file(s1, buf);
19113 }
19114
19115 if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
19116 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
19117 }
19118 }
19119
19120
19121
19122
19123 static void tcc_add_linker_symbols(TCCState *s1)
19124 {
19125 char buf[1024];
19126 int i;
19127 Section *s;
19128
19129 add_elf_sym(symtab_section,
19130 text_section->data_offset, 0,
19131 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19132 text_section->sh_num, "_etext");
19133 add_elf_sym(symtab_section,
19134 data_section->data_offset, 0,
19135 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19136 data_section->sh_num, "_edata");
19137 add_elf_sym(symtab_section,
19138 bss_section->data_offset, 0,
19139 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19140 bss_section->sh_num, "_end");
19141
19142 (s1, ".preinit_array");
19143 add_init_array_defines(s1, ".init_array");
19144 add_init_array_defines(s1, ".fini_array");
19145
19146
19147
19148 for(i = 1; i < s1->nb_sections; i++) {
19149 s = s1->sections[i];
19150 if (s->sh_type == SHT_PROGBITS &&
19151 (s->sh_flags & SHF_ALLOC)) {
19152 const char *p;
19153 int ch;
19154
19155
19156 = s->name;
19157 for(;;) {
19158 ch = *p;
19159 if (!ch)
19160 break;
19161 if (!isid(ch) && !isnum(ch))
19162 goto next_sec;
19163 p++;
19164 }
19165 snprintf(buf, sizeof(buf), "__start_%s", s->name);
19166 add_elf_sym(symtab_section,
19167 0, 0,
19168 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19169 s->sh_num, buf);
19170 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
19171 add_elf_sym(symtab_section,
19172 s->data_offset, 0,
19173 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19174 s->sh_num, buf);
19175 }
19176 next_sec: ;
19177 }
19178 }
19179
19180
19181 #ifdef __FreeBSD__
19182 static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
19183 #else
19184 static char elf_interp[] = "/lib/ld-linux.so.2";
19185 #endif
19186
19187 static void tcc_output_binary(TCCState *s1, FILE *f,
19188 const int *section_order)
19189 {
19190 Section *s;
19191 int i, offset, size;
19192
19193 offset = 0;
19194 for(i=1;i<s1->nb_sections;i++) {
19195 s = s1->sections[section_order[i]];
19196 if (s->sh_type != SHT_NOBITS &&
19197 (s->sh_flags & SHF_ALLOC)) {
19198 while (offset < s->sh_offset) {
19199 fputc(0, f);
19200 offset++;
19201 }
19202 size = s->sh_size;
19203 dummy_size_t = fwrite(s->data, 1, size, f);
19204 offset += size;
19205 }
19206 }
19207 }
19208
19209
19210
19211 int tcc_output_file(TCCState *s1, const char *filename)
19212 {
19213 Elf32_Ehdr ehdr;
19214 FILE *f;
19215 int fd, mode, ret;
19216 int *section_order;
19217 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
19218 unsigned long addr;
19219 Section *strsec, *s;
19220 Elf32_Shdr shdr, *sh;
19221 Elf32_Phdr *phdr, *ph;
19222 Section *interp, *dynamic, *dynstr;
19223 unsigned long saved_dynamic_data_offset;
19224 Elf32_Sym *sym;
19225 int type, file_type;
19226 unsigned long rel_addr, rel_size;
19227
19228 file_type = s1->output_type;
19229 s1->nb_errors = 0;
19230
19231 if (file_type != TCC_OUTPUT_OBJ) {
19232 tcc_add_runtime(s1);
19233 }
19234
19235 phdr = NULL;
19236 section_order = NULL;
19237 interp = NULL;
19238 dynamic = NULL;
19239 dynstr = NULL;
19240 = 0;
19241
19242 if (file_type != TCC_OUTPUT_OBJ) {
19243 relocate_common_syms();
19244
19245 tcc_add_linker_symbols(s1);
19246
19247 if (!s1->static_link) {
19248 const char *name;
19249 int sym_index, index;
19250 Elf32_Sym *esym, *sym_end;
19251
19252 if (file_type == TCC_OUTPUT_EXE) {
19253 char *ptr;
19254
19255 = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
19256 interp->sh_addralign = 1;
19257 ptr = section_ptr_add(interp, sizeof(elf_interp));
19258 strcpy(ptr, elf_interp);
19259 }
19260
19261
19262 ->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
19263 ".dynstr",
19264 ".hash", SHF_ALLOC);
19265 dynstr = s1->dynsym->link;
19266
19267
19268 = new_section(s1, ".dynamic", SHT_DYNAMIC,
19269 SHF_ALLOC | SHF_WRITE);
19270 dynamic->link = dynstr;
19271 dynamic->sh_entsize = sizeof(Elf32_Dyn);
19272
19273
19274 ->plt = new_section(s1, ".plt", SHT_PROGBITS,
19275 SHF_ALLOC | SHF_EXECINSTR);
19276 s1->plt->sh_entsize = 4;
19277
19278 build_got(s1);
19279
19280
19281
19282
19283
19284 = (Elf32_Sym *)(symtab_section->data +
19285 symtab_section->data_offset);
19286 if (file_type == TCC_OUTPUT_EXE) {
19287 for(sym = (Elf32_Sym *)symtab_section->data + 1;
19288 sym < sym_end;
19289 sym++) {
19290 if (sym->st_shndx == SHN_UNDEF) {
19291 name = symtab_section->link->data + sym->st_name;
19292 sym_index = find_elf_sym(s1->dynsymtab_section, name);
19293 if (sym_index) {
19294 esym = &((Elf32_Sym *)s1->dynsymtab_section->data)[sym_index];
19295 type = ELF32_ST_TYPE(esym->st_info);
19296 if (type == STT_FUNC) {
19297 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
19298 esym->st_info,
19299 sym - (Elf32_Sym *)symtab_section->data);
19300 } else if (type == STT_OBJECT) {
19301 unsigned long offset;
19302 offset = bss_section->data_offset;
19303
19304 = (offset + 16 - 1) & -16;
19305 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
19306 esym->st_info, 0,
19307 bss_section->sh_num, name);
19308 put_elf_reloc(s1->dynsym, bss_section,
19309 offset, R_COPY, index);
19310 offset += esym->st_size;
19311 bss_section->data_offset = offset;
19312 }
19313 } else {
19314
19315
19316
19317 if (ELF32_ST_BIND(sym->st_info) == STB_WEAK ||
19318 !strcmp(name, "_fp_hw")) {
19319 } else {
19320 error_noabort("undefined symbol '%s'", name);
19321 }
19322 }
19323 } else if (s1->rdynamic &&
19324 ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
19325
19326
19327 = symtab_section->link->data + sym->st_name;
19328 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
19329 sym->st_info, 0,
19330 sym->st_shndx, name);
19331 }
19332 }
19333
19334 if (s1->nb_errors)
19335 goto fail;
19336
19337
19338
19339 = (Elf32_Sym *)(s1->dynsymtab_section->data +
19340 s1->dynsymtab_section->data_offset);
19341 for(esym = (Elf32_Sym *)s1->dynsymtab_section->data + 1;
19342 esym < sym_end;
19343 esym++) {
19344 if (esym->st_shndx == SHN_UNDEF) {
19345 name = s1->dynsymtab_section->link->data + esym->st_name;
19346 sym_index = find_elf_sym(symtab_section, name);
19347 if (sym_index) {
19348
19349
19350 = &((Elf32_Sym *)symtab_section->data)[sym_index];
19351 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
19352 sym->st_info, 0,
19353 sym->st_shndx, name);
19354 } else {
19355 if (ELF32_ST_BIND(esym->st_info) == STB_WEAK) {
19356
19357 } else {
19358 warning("undefined dynamic symbol '%s'", name);
19359 }
19360 }
19361 }
19362 }
19363 } else {
19364 int nb_syms;
19365
19366 = symtab_section->data_offset / sizeof(Elf32_Sym);
19367 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
19368 for(sym = (Elf32_Sym *)symtab_section->data + 1;
19369 sym < sym_end;
19370 sym++) {
19371 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
19372 name = symtab_section->link->data + sym->st_name;
19373 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
19374 sym->st_info, 0,
19375 sym->st_shndx, name);
19376 s1->symtab_to_dynsym[sym -
19377 (Elf32_Sym *)symtab_section->data] =
19378 index;
19379 }
19380 }
19381 }
19382
19383 build_got_entries(s1);
19384
19385
19386 for(i = 0; i < s1->nb_loaded_dlls; i++) {
19387 DLLReference *dllref = s1->loaded_dlls[i];
19388 if (dllref->level == 0)
19389 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
19390 }
19391
19392
19393 if (file_type == TCC_OUTPUT_DLL)
19394 put_dt(dynamic, DT_TEXTREL, 0);
19395
19396
19397 = dynamic->data_offset;
19398 dynamic->data_offset += 8 * 9;
19399 } else {
19400
19401 (s1);
19402 }
19403 }
19404
19405 memset(&ehdr, 0, sizeof(ehdr));
19406
19407
19408 = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
19409 put_elf_str(strsec, "");
19410
19411
19412 = s1->nb_sections;
19413
19414
19415 = tcc_malloc(sizeof(int) * shnum);
19416 section_order[0] = 0;
19417 sh_order_index = 1;
19418
19419
19420 switch(file_type) {
19421 default:
19422 case TCC_OUTPUT_OBJ:
19423 phnum = 0;
19424 break;
19425 case TCC_OUTPUT_EXE:
19426 if (!s1->static_link)
19427 phnum = 4;
19428 else
19429 phnum = 2;
19430 break;
19431 case TCC_OUTPUT_DLL:
19432 phnum = 3;
19433 break;
19434 }
19435
19436
19437
19438
19439
19440 for(i = 1; i < s1->nb_sections; i++) {
19441 s = s1->sections[i];
19442 s->sh_name = put_elf_str(strsec, s->name);
19443
19444
19445 if (file_type == TCC_OUTPUT_DLL &&
19446 s->sh_type == SHT_REL &&
19447 !(s->sh_flags & SHF_ALLOC)) {
19448 prepare_dynamic_rel(s1, s);
19449 } else if (do_debug ||
19450 file_type == TCC_OUTPUT_OBJ ||
19451 (s->sh_flags & SHF_ALLOC) ||
19452 i == (s1->nb_sections - 1)) {
19453
19454 ->sh_size = s->data_offset;
19455 }
19456 }
19457
19458
19459 = tcc_mallocz(phnum * sizeof(Elf32_Phdr));
19460
19461 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
19462 file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
19463 } else {
19464 file_offset = 0;
19465 }
19466 if (phnum > 0) {
19467
19468 if (s1->has_text_addr) {
19469 int a_offset, p_offset;
19470 addr = s1->text_addr;
19471
19472
19473 = addr & (ELF_PAGE_SIZE - 1);
19474 p_offset = file_offset & (ELF_PAGE_SIZE - 1);
19475 if (a_offset < p_offset)
19476 a_offset += ELF_PAGE_SIZE;
19477 file_offset += (a_offset - p_offset);
19478 } else {
19479 if (file_type == TCC_OUTPUT_DLL)
19480 addr = 0;
19481 else
19482 addr = ELF_START_ADDR;
19483
19484 += (file_offset & (ELF_PAGE_SIZE - 1));
19485 }
19486
19487
19488 = 0;
19489 rel_addr = 0;
19490
19491
19492 = &phdr[0];
19493 if (interp)
19494 ph++;
19495
19496 for(j = 0; j < 2; j++) {
19497 ph->p_type = PT_LOAD;
19498 if (j == 0)
19499 ph->p_flags = PF_R | PF_X;
19500 else
19501 ph->p_flags = PF_R | PF_W;
19502 ph->p_align = ELF_PAGE_SIZE;
19503
19504
19505
19506
19507 for(k = 0; k < 5; k++) {
19508 for(i = 1; i < s1->nb_sections; i++) {
19509 s = s1->sections[i];
19510
19511 if (j == 0) {
19512 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
19513 SHF_ALLOC)
19514 continue;
19515 } else {
19516 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
19517 (SHF_ALLOC | SHF_WRITE))
19518 continue;
19519 }
19520 if (s == interp) {
19521 if (k != 0)
19522 continue;
19523 } else if (s->sh_type == SHT_DYNSYM ||
19524 s->sh_type == SHT_STRTAB ||
19525 s->sh_type == SHT_HASH) {
19526 if (k != 1)
19527 continue;
19528 } else if (s->sh_type == SHT_REL) {
19529 if (k != 2)
19530 continue;
19531 } else if (s->sh_type == SHT_NOBITS) {
19532 if (k != 4)
19533 continue;
19534 } else {
19535 if (k != 3)
19536 continue;
19537 }
19538 section_order[sh_order_index++] = i;
19539
19540
19541 = addr;
19542 addr = (addr + s->sh_addralign - 1) &
19543 ~(s->sh_addralign - 1);
19544 file_offset += addr - tmp;
19545 s->sh_offset = file_offset;
19546 s->sh_addr = addr;
19547
19548
19549 if (ph->p_offset == 0) {
19550 ph->p_offset = file_offset;
19551 ph->p_vaddr = addr;
19552 ph->p_paddr = ph->p_vaddr;
19553 }
19554
19555 if (s->sh_type == SHT_REL) {
19556 if (rel_size == 0)
19557 rel_addr = addr;
19558 rel_size += s->sh_size;
19559 }
19560 addr += s->sh_size;
19561 if (s->sh_type != SHT_NOBITS)
19562 file_offset += s->sh_size;
19563 }
19564 }
19565 ph->p_filesz = file_offset - ph->p_offset;
19566 ph->p_memsz = addr - ph->p_vaddr;
19567 ph++;
19568 if (j == 0) {
19569 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
19570
19571
19572 if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
19573 addr += ELF_PAGE_SIZE;
19574 } else {
19575 addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1);
19576 file_offset = (file_offset + ELF_PAGE_SIZE - 1) &
19577 ~(ELF_PAGE_SIZE - 1);
19578 }
19579 }
19580 }
19581
19582
19583 if (interp) {
19584 ph = &phdr[0];
19585
19586 ph->p_type = PT_INTERP;
19587 ph->p_offset = interp->sh_offset;
19588 ph->p_vaddr = interp->sh_addr;
19589 ph->p_paddr = ph->p_vaddr;
19590 ph->p_filesz = interp->sh_size;
19591 ph->p_memsz = interp->sh_size;
19592 ph->p_flags = PF_R;
19593 ph->p_align = interp->sh_addralign;
19594 }
19595
19596
19597 if (dynamic) {
19598 Elf32_Sym *sym_end;
19599
19600 ph = &phdr[phnum - 1];
19601
19602 ph->p_type = PT_DYNAMIC;
19603 ph->p_offset = dynamic->sh_offset;
19604 ph->p_vaddr = dynamic->sh_addr;
19605 ph->p_paddr = ph->p_vaddr;
19606 ph->p_filesz = dynamic->sh_size;
19607 ph->p_memsz = dynamic->sh_size;
19608 ph->p_flags = PF_R | PF_W;
19609 ph->p_align = dynamic->sh_addralign;
19610
19611
19612 (s1->got->data, dynamic->sh_addr);
19613
19614
19615 if (file_type == TCC_OUTPUT_EXE) {
19616 uint8_t *p, *p_end;
19617
19618 p = s1->plt->data;
19619 p_end = p + s1->plt->data_offset;
19620 if (p < p_end) {
19621 #if defined(TCC_TARGET_I386)
19622 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
19623 put32(p + 8, get32(p + 8) + s1->got->sh_addr);
19624 p += 16;
19625 while (p < p_end) {
19626 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
19627 p += 16;
19628 }
19629 #elif defined(TCC_TARGET_ARM)
19630 int x;
19631 x=s1->got->sh_addr - s1->plt->sh_addr - 12;
19632 p +=16;
19633 while (p < p_end) {
19634 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
19635 p += 16;
19636 }
19637 #elif defined(TCC_TARGET_C67)
19638
19639 #else
19640 #error unsupported CPU
19641 #endif
19642 }
19643 }
19644
19645
19646 = (Elf32_Sym *)(s1->dynsym->data + s1->dynsym->data_offset);
19647 for(sym = (Elf32_Sym *)s1->dynsym->data + 1;
19648 sym < sym_end;
19649 sym++) {
19650 if (sym->st_shndx == SHN_UNDEF) {
19651
19652
19653 if (sym->st_value)
19654 sym->st_value += s1->plt->sh_addr;
19655 } else if (sym->st_shndx < SHN_LORESERVE) {
19656
19657 ->st_value += s1->sections[sym->st_shndx]->sh_addr;
19658 }
19659 }
19660
19661
19662 ->data_offset = saved_dynamic_data_offset;
19663 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
19664 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
19665 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
19666 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
19667 put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym));
19668 put_dt(dynamic, DT_REL, rel_addr);
19669 put_dt(dynamic, DT_RELSZ, rel_size);
19670 put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel));
19671 put_dt(dynamic, DT_NULL, 0);
19672 }
19673
19674 ehdr.e_phentsize = sizeof(Elf32_Phdr);
19675 ehdr.e_phnum = phnum;
19676 ehdr.e_phoff = sizeof(Elf32_Ehdr);
19677 }
19678
19679
19680 for(i = 1; i < s1->nb_sections; i++) {
19681 s = s1->sections[i];
19682 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
19683 continue;
19684 section_order[sh_order_index++] = i;
19685
19686 file_offset = (file_offset + s->sh_addralign - 1) &
19687 ~(s->sh_addralign - 1);
19688 s->sh_offset = file_offset;
19689 if (s->sh_type != SHT_NOBITS)
19690 file_offset += s->sh_size;
19691 }
19692
19693
19694
19695 if (file_type != TCC_OUTPUT_OBJ) {
19696 relocate_syms(s1, 0);
19697
19698 if (s1->nb_errors != 0) {
19699 fail:
19700 ret = -1;
19701 goto the_end;
19702 }
19703
19704
19705
19706 for(i = 1; i < s1->nb_sections; i++) {
19707 s = s1->sections[i];
19708 if (s->reloc && s != s1->got)
19709 relocate_section(s1, s);
19710 }
19711
19712
19713
19714 for(i = 1; i < s1->nb_sections; i++) {
19715 s = s1->sections[i];
19716 if ((s->sh_flags & SHF_ALLOC) &&
19717 s->sh_type == SHT_REL) {
19718 relocate_rel(s1, s);
19719 }
19720 }
19721
19722
19723 if (file_type == TCC_OUTPUT_EXE)
19724 ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start");
19725 else
19726 ehdr.e_entry = text_section->sh_addr;
19727 }
19728
19729
19730 if (file_type == TCC_OUTPUT_OBJ)
19731 mode = 0666;
19732 else
19733 mode = 0777;
19734 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
19735 if (fd < 0) {
19736 error_noabort("could not write '%s'", filename);
19737 goto fail;
19738 }
19739 f = fdopen(fd, "wb");
19740
19741 #ifdef TCC_TARGET_COFF
19742 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
19743 tcc_output_coff(s1, f);
19744 } else
19745 #endif
19746 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
19747 sort_syms(s1, symtab_section);
19748
19749
19750 = (file_offset + 3) & -4;
19751
19752
19753 .e_ident[0] = ELFMAG0;
19754 ehdr.e_ident[1] = ELFMAG1;
19755 ehdr.e_ident[2] = ELFMAG2;
19756 ehdr.e_ident[3] = ELFMAG3;
19757 ehdr.e_ident[4] = ELFCLASS32;
19758 ehdr.e_ident[5] = ELFDATA2LSB;
19759 ehdr.e_ident[6] = EV_CURRENT;
19760 #ifdef __FreeBSD__
19761 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
19762 #endif
19763 #ifdef TCC_TARGET_ARM
19764 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
19765 #endif
19766 switch(file_type) {
19767 default:
19768 case TCC_OUTPUT_EXE:
19769 ehdr.e_type = ET_EXEC;
19770 break;
19771 case TCC_OUTPUT_DLL:
19772 ehdr.e_type = ET_DYN;
19773 break;
19774 case TCC_OUTPUT_OBJ:
19775 ehdr.e_type = ET_REL;
19776 break;
19777 }
19778 ehdr.e_machine = EM_TCC_TARGET;
19779 ehdr.e_version = EV_CURRENT;
19780 ehdr.e_shoff = file_offset;
19781 ehdr.e_ehsize = sizeof(Elf32_Ehdr);
19782 ehdr.e_shentsize = sizeof(Elf32_Shdr);
19783 ehdr.e_shnum = shnum;
19784 ehdr.e_shstrndx = shnum - 1;
19785
19786 dummy_size_t = fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
19787 dummy_size_t = fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
19788 offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
19789
19790 for(i=1;i<s1->nb_sections;i++) {
19791 s = s1->sections[section_order[i]];
19792 if (s->sh_type != SHT_NOBITS) {
19793 while (offset < s->sh_offset) {
19794 fputc(0, f);
19795 offset++;
19796 }
19797 size = s->sh_size;
19798 dummy_size_t = fwrite(s->data, 1, size, f);
19799 offset += size;
19800 }
19801 }
19802
19803
19804 while (offset < ehdr.e_shoff) {
19805 fputc(0, f);
19806 offset++;
19807 }
19808
19809 for(i=0;i<s1->nb_sections;i++) {
19810 sh = &shdr;
19811 memset(sh, 0, sizeof(Elf32_Shdr));
19812 s = s1->sections[i];
19813 if (s) {
19814 sh->sh_name = s->sh_name;
19815 sh->sh_type = s->sh_type;
19816 sh->sh_flags = s->sh_flags;
19817 sh->sh_entsize = s->sh_entsize;
19818 sh->sh_info = s->sh_info;
19819 if (s->link)
19820 sh->sh_link = s->link->sh_num;
19821 sh->sh_addralign = s->sh_addralign;
19822 sh->sh_addr = s->sh_addr;
19823 sh->sh_offset = s->sh_offset;
19824 sh->sh_size = s->sh_size;
19825 }
19826 dummy_size_t = fwrite(sh, 1, sizeof(Elf32_Shdr), f);
19827 }
19828 } else {
19829 tcc_output_binary(s1, f, section_order);
19830 }
19831 fclose(f);
19832
19833 ret = 0;
19834 the_end:
19835 tcc_free(s1->symtab_to_dynsym);
19836 tcc_free(section_order);
19837 tcc_free(phdr);
19838 tcc_free(s1->got_offsets);
19839 return ret;
19840 }
19841
19842 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
19843 {
19844 void *data;
19845
19846 data = tcc_malloc(size);
19847 lseek(fd, file_offset, SEEK_SET);
19848 dummy_size_t = read(fd, data, size);
19849 return data;
19850 }
19851
19852 typedef struct SectionMergeInfo {
19853 Section *s;
19854 unsigned long offset;
19855 ;
19856 ;
19857 } SectionMergeInfo;
19858
19859
19860
19861 static int tcc_load_object_file(TCCState *s1,
19862 int fd, unsigned long file_offset)
19863 {
19864 Elf32_Ehdr ehdr;
19865 Elf32_Shdr *shdr, *sh;
19866 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
19867 unsigned char *strsec, *strtab;
19868 int *old_to_new_syms;
19869 char *sh_name, *name;
19870 SectionMergeInfo *sm_table, *sm;
19871 Elf32_Sym *sym, *symtab;
19872 Elf32_Rel *rel, *rel_end;
19873 Section *s;
19874
19875 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
19876 goto fail1;
19877 if (ehdr.e_ident[0] != ELFMAG0 ||
19878 ehdr.e_ident[1] != ELFMAG1 ||
19879 ehdr.e_ident[2] != ELFMAG2 ||
19880 ehdr.e_ident[3] != ELFMAG3)
19881 goto fail1;
19882
19883 if (ehdr.e_type != ET_REL)
19884 goto fail1;
19885
19886 if (ehdr.e_ident[5] != ELFDATA2LSB ||
19887 ehdr.e_machine != EM_TCC_TARGET) {
19888 fail1:
19889 error_noabort("invalid object file");
19890 return -1;
19891 }
19892
19893 = load_data(fd, file_offset + ehdr.e_shoff,
19894 sizeof(Elf32_Shdr) * ehdr.e_shnum);
19895 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
19896
19897
19898 = &shdr[ehdr.e_shstrndx];
19899 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
19900
19901
19902 = NULL;
19903 symtab = NULL;
19904 strtab = NULL;
19905 nb_syms = 0;
19906 for(i = 1; i < ehdr.e_shnum; i++) {
19907 sh = &shdr[i];
19908 if (sh->sh_type == SHT_SYMTAB) {
19909 if (symtab) {
19910 error_noabort("object must contain only one symtab");
19911 fail:
19912 ret = -1;
19913 goto the_end;
19914 }
19915 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
19916 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
19917 sm_table[i].s = symtab_section;
19918
19919
19920 = &shdr[sh->sh_link];
19921 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
19922 }
19923 }
19924
19925
19926
19927 for(i = 1; i < ehdr.e_shnum; i++) {
19928
19929 if (i == ehdr.e_shstrndx)
19930 continue;
19931 sh = &shdr[i];
19932 sh_name = strsec + sh->sh_name;
19933
19934 if (sh->sh_type != SHT_PROGBITS &&
19935 sh->sh_type != SHT_REL &&
19936 sh->sh_type != SHT_NOBITS)
19937 continue;
19938 if (sh->sh_addralign < 1)
19939 sh->sh_addralign = 1;
19940
19941 for(j = 1; j < s1->nb_sections;j++) {
19942 s = s1->sections[j];
19943 if (!strcmp(s->name, sh_name)) {
19944 if (!strncmp(sh_name, ".gnu.linkonce",
19945 sizeof(".gnu.linkonce") - 1)) {
19946
19947
19948
19949
19950 [i].link_once = 1;
19951 goto next;
19952 } else {
19953 goto found;
19954 }
19955 }
19956 }
19957
19958 = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
19959
19960
19961 ->sh_addralign = sh->sh_addralign;
19962 s->sh_entsize = sh->sh_entsize;
19963 sm_table[i].new_section = 1;
19964 found:
19965 if (sh->sh_type != s->sh_type) {
19966 error_noabort("invalid section type");
19967 goto fail;
19968 }
19969
19970
19971 = s->data_offset;
19972 size = sh->sh_addralign - 1;
19973 offset = (offset + size) & ~size;
19974 if (sh->sh_addralign > s->sh_addralign)
19975 s->sh_addralign = sh->sh_addralign;
19976 s->data_offset = offset;
19977 sm_table[i].offset = offset;
19978 sm_table[i].s = s;
19979
19980 = sh->sh_size;
19981 if (sh->sh_type != SHT_NOBITS) {
19982 unsigned char *ptr;
19983 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
19984 ptr = section_ptr_add(s, size);
19985 dummy_size_t = read(fd, ptr, size);
19986 } else {
19987 s->data_offset += size;
19988 }
19989 next: ;
19990 }
19991
19992
19993
19994 = sm_table;
19995 for(i = 1; i < ehdr.e_shnum; i++) {
19996 s = sm_table[i].s;
19997 if (!s || !sm_table[i].new_section)
19998 continue;
19999 sh = &shdr[i];
20000 if (sh->sh_link > 0)
20001 s->link = sm_table[sh->sh_link].s;
20002 if (sh->sh_type == SHT_REL) {
20003 s->sh_info = sm_table[sh->sh_info].s->sh_num;
20004
20005 ->sections[s->sh_info]->reloc = s;
20006 }
20007 }
20008
20009
20010 = tcc_mallocz(nb_syms * sizeof(int));
20011
20012 sym = symtab + 1;
20013 for(i = 1; i < nb_syms; i++, sym++) {
20014 if (sym->st_shndx != SHN_UNDEF &&
20015 sym->st_shndx < SHN_LORESERVE) {
20016 sm = &sm_table[sym->st_shndx];
20017 if (sm->link_once) {
20018
20019
20020
20021 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
20022 name = strtab + sym->st_name;
20023 sym_index = find_elf_sym(symtab_section, name);
20024 if (sym_index)
20025 old_to_new_syms[i] = sym_index;
20026 }
20027 continue;
20028 }
20029
20030 if (!sm->s)
20031 continue;
20032
20033 ->st_shndx = sm->s->sh_num;
20034
20035 ->st_value += sm->offset;
20036 }
20037
20038 = strtab + sym->st_name;
20039 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
20040 sym->st_info, sym->st_other,
20041 sym->st_shndx, name);
20042 old_to_new_syms[i] = sym_index;
20043 }
20044
20045
20046 for(i = 1; i < ehdr.e_shnum; i++) {
20047 s = sm_table[i].s;
20048 if (!s)
20049 continue;
20050 sh = &shdr[i];
20051 offset = sm_table[i].offset;
20052 switch(s->sh_type) {
20053 case SHT_REL:
20054
20055 = sm_table[sh->sh_info].offset;
20056 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
20057 for(rel = (Elf32_Rel *)(s->data + offset);
20058 rel < rel_end;
20059 rel++) {
20060 int type;
20061 unsigned sym_index;
20062
20063 = ELF32_R_TYPE(rel->r_info);
20064 sym_index = ELF32_R_SYM(rel->r_info);
20065
20066 if (sym_index >= nb_syms)
20067 goto invalid_reloc;
20068 sym_index = old_to_new_syms[sym_index];
20069 if (!sym_index) {
20070 invalid_reloc:
20071 error_noabort("Invalid relocation entry");
20072 goto fail;
20073 }
20074 rel->r_info = ELF32_R_INFO(sym_index, type);
20075
20076 ->r_offset += offseti;
20077 }
20078 break;
20079 default:
20080 break;
20081 }
20082 }
20083
20084 ret = 0;
20085 the_end:
20086 tcc_free(symtab);
20087 tcc_free(strtab);
20088 tcc_free(old_to_new_syms);
20089 tcc_free(sm_table);
20090 tcc_free(strsec);
20091 tcc_free(shdr);
20092 return ret;
20093 }
20094
20095 #define ARMAG "!<arch>\012"
20096
20097 typedef struct ArchiveHeader {
20098 char ar_name[16];
20099 char ar_date[12];
20100 char ar_uid[6];
20101 char ar_gid[6];
20102 char ar_mode[8];
20103 char ar_size[10];
20104 char ar_fmag[2];
20105 } ArchiveHeader;
20106
20107 static int get_be32(const uint8_t *b)
20108 {
20109 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
20110 }
20111
20112
20113 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
20114 {
20115 int i, bound, nsyms, sym_index, off, ret;
20116 uint8_t *data;
20117 const char *ar_names, *p;
20118 const uint8_t *ar_index;
20119 Elf32_Sym *sym;
20120
20121 data = tcc_malloc(size);
20122 if (read(fd, data, size) != size)
20123 goto fail;
20124 nsyms = get_be32(data);
20125 ar_index = data + 4;
20126 ar_names = ar_index + nsyms * 4;
20127
20128 do {
20129 bound = 0;
20130 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
20131 sym_index = find_elf_sym(symtab_section, p);
20132 if(sym_index) {
20133 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
20134 if(sym->st_shndx == SHN_UNDEF) {
20135 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
20136 #if 0
20137 printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
20138 #endif
20139 ++bound;
20140 lseek(fd, off, SEEK_SET);
20141 if(tcc_load_object_file(s1, fd, off) < 0) {
20142 fail:
20143 ret = -1;
20144 goto the_end;
20145 }
20146 }
20147 }
20148 }
20149 } while(bound);
20150 ret = 0;
20151 the_end:
20152 tcc_free(data);
20153 return ret;
20154 }
20155
20156
20157 static int tcc_load_archive(TCCState *s1, int fd)
20158 {
20159 ArchiveHeader hdr;
20160 char ar_size[11];
20161 char ar_name[17];
20162 char magic[8];
20163 int size, len, i;
20164 unsigned long file_offset;
20165
20166
20167 = read(fd, magic, sizeof(magic));
20168
20169 for(;;) {
20170 len = read(fd, &hdr, sizeof(hdr));
20171 if (len == 0)
20172 break;
20173 if (len != sizeof(hdr)) {
20174 error_noabort("invalid archive");
20175 return -1;
20176 }
20177 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
20178 ar_size[sizeof(hdr.ar_size)] = '\0';
20179 size = strtol(ar_size, NULL, 0);
20180 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
20181 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
20182 if (ar_name[i] != ' ')
20183 break;
20184 }
20185 ar_name[i + 1] = '\0';
20186
20187 = lseek(fd, 0, SEEK_CUR);
20188
20189 = (size + 1) & ~1;
20190 if (!strcmp(ar_name, "/")) {
20191
20192 if(s1->alacarte_link)
20193 return tcc_load_alacarte(s1, fd, size);
20194 } else if (!strcmp(ar_name, "//") ||
20195 !strcmp(ar_name, "__.SYMDEF") ||
20196 !strcmp(ar_name, "__.SYMDEF/") ||
20197 !strcmp(ar_name, "ARFILENAMES/")) {
20198
20199 } else {
20200 if (tcc_load_object_file(s1, fd, file_offset) < 0)
20201 return -1;
20202 }
20203 lseek(fd, file_offset + size, SEEK_SET);
20204 }
20205 return 0;
20206 }
20207
20208
20209
20210
20211 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
20212 {
20213 Elf32_Ehdr ehdr;
20214 Elf32_Shdr *shdr, *sh, *sh1;
20215 int i, nb_syms, nb_dts, sym_bind, ret;
20216 Elf32_Sym *sym, *dynsym;
20217 Elf32_Dyn *dt, *dynamic;
20218 unsigned char *dynstr;
20219 const char *name, *soname, *p;
20220 DLLReference *dllref;
20221
20222 dummy_size_t = read(fd, &ehdr, sizeof(ehdr));
20223
20224
20225 if (ehdr.e_ident[5] != ELFDATA2LSB ||
20226 ehdr.e_machine != EM_TCC_TARGET) {
20227 error_noabort("bad architecture");
20228 return -1;
20229 }
20230
20231
20232 = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum);
20233
20234
20235 = 0;
20236 nb_dts = 0;
20237 dynamic = NULL;
20238 dynsym = NULL;
20239 = NULL;
20240 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
20241 switch(sh->sh_type) {
20242 case SHT_DYNAMIC:
20243 nb_dts = sh->sh_size / sizeof(Elf32_Dyn);
20244 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
20245 break;
20246 case SHT_DYNSYM:
20247 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
20248 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
20249 sh1 = &shdr[sh->sh_link];
20250 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
20251 break;
20252 default:
20253 break;
20254 }
20255 }
20256
20257
20258 = filename;
20259 p = strrchr(soname, '/');
20260 if (p)
20261 soname = p + 1;
20262
20263 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
20264 if (dt->d_tag == DT_SONAME) {
20265 soname = dynstr + dt->d_un.d_val;
20266 }
20267 }
20268
20269
20270 for(i = 0; i < s1->nb_loaded_dlls; i++) {
20271 dllref = s1->loaded_dlls[i];
20272 if (!strcmp(soname, dllref->name)) {
20273
20274 if (level < dllref->level)
20275 dllref->level = level;
20276 ret = 0;
20277 goto the_end;
20278 }
20279 }
20280
20281
20282
20283
20284 = tcc_malloc(sizeof(DLLReference) + strlen(soname));
20285 dllref->level = level;
20286 strcpy(dllref->name, soname);
20287 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
20288
20289
20290 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
20291 sym_bind = ELF32_ST_BIND(sym->st_info);
20292 if (sym_bind == STB_LOCAL)
20293 continue;
20294 name = dynstr + sym->st_name;
20295 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
20296 sym->st_info, sym->st_other, sym->st_shndx, name);
20297 }
20298
20299
20300 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
20301 switch(dt->d_tag) {
20302 case DT_NEEDED:
20303 name = dynstr + dt->d_un.d_val;
20304 for(i = 0; i < s1->nb_loaded_dlls; i++) {
20305 dllref = s1->loaded_dlls[i];
20306 if (!strcmp(name, dllref->name))
20307 goto already_loaded;
20308 }
20309 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
20310 error_noabort("referenced dll '%s' not found", name);
20311 ret = -1;
20312 goto the_end;
20313 }
20314 already_loaded:
20315 break;
20316 }
20317 }
20318 ret = 0;
20319 the_end:
20320 tcc_free(dynstr);
20321 tcc_free(dynsym);
20322 tcc_free(dynamic);
20323 tcc_free(shdr);
20324 return ret;
20325 }
20326
20327 #define LD_TOK_NAME 256
20328 #define LD_TOK_EOF (-1)
20329
20330
20331 static int ld_next(TCCState *s1, char *name, int name_size)
20332 {
20333 int c;
20334 char *q;
20335
20336 redo:
20337 switch(ch) {
20338 case ' ':
20339 case '\t':
20340 case '\f':
20341 case '\v':
20342 case '\r':
20343 case '\n':
20344 inp();
20345 goto redo;
20346 case '/':
20347 minp();
20348 if (ch == '*') {
20349 file->buf_ptr = parse_comment(file->buf_ptr);
20350 ch = file->buf_ptr[0];
20351 goto redo;
20352 } else {
20353 q = name;
20354 *q++ = '/';
20355 goto parse_name;
20356 }
20357 break;
20358 case 'a' ... 'z':
20359 case 'A' ... 'Z':
20360 case '_':
20361 case '\\':
20362 case '.':
20363 case '$':
20364 case '~':
20365 q = name;
20366 parse_name:
20367 for(;;) {
20368 if (!((ch >= 'a' && ch <= 'z') ||
20369 (ch >= 'A' && ch <= 'Z') ||
20370 (ch >= '0' && ch <= '9') ||
20371 strchr("/.-_+=$:\\,~", ch)))
20372 break;
20373 if ((q - name) < name_size - 1) {
20374 *q++ = ch;
20375 }
20376 minp();
20377 }
20378 *q = '\0';
20379 c = LD_TOK_NAME;
20380 break;
20381 case CH_EOF:
20382 c = LD_TOK_EOF;
20383 break;
20384 default:
20385 c = ch;
20386 inp();
20387 break;
20388 }
20389 #if 0
20390 printf("tok=%c %d\n", c, c);
20391 if (c == LD_TOK_NAME)
20392 printf(" name=%s\n", name);
20393 #endif
20394 return c;
20395 }
20396
20397
20398
20399 static int tcc_load_ldscript(TCCState *s1)
20400 {
20401 char cmd[64];
20402 char filename[1024];
20403 int t;
20404
20405 ch = file->buf_ptr[0];
20406 ch = handle_eob();
20407 for(;;) {
20408 t = ld_next(s1, cmd, sizeof(cmd));
20409 if (t == LD_TOK_EOF)
20410 return 0;
20411 else if (t != LD_TOK_NAME)
20412 return -1;
20413 if (!strcmp(cmd, "INPUT") ||
20414 !strcmp(cmd, "GROUP")) {
20415 t = ld_next(s1, cmd, sizeof(cmd));
20416 if (t != '(')
20417 expect("(");
20418 t = ld_next(s1, filename, sizeof(filename));
20419 for(;;) {
20420 if (t == LD_TOK_EOF) {
20421 error_noabort("unexpected end of file");
20422 return -1;
20423 } else if (t == ')') {
20424 break;
20425 } else if (t != LD_TOK_NAME) {
20426 error_noabort("filename expected");
20427 return -1;
20428 }
20429 tcc_add_file(s1, filename);
20430 t = ld_next(s1, filename, sizeof(filename));
20431 if (t == ',') {
20432 t = ld_next(s1, filename, sizeof(filename));
20433 }
20434 }
20435 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
20436 !strcmp(cmd, "TARGET")) {
20437
20438 = ld_next(s1, cmd, sizeof(cmd));
20439 if (t != '(')
20440 expect("(");
20441 for(;;) {
20442 t = ld_next(s1, filename, sizeof(filename));
20443 if (t == LD_TOK_EOF) {
20444 error_noabort("unexpected end of file");
20445 return -1;
20446 } else if (t == ')') {
20447 break;
20448 }
20449 }
20450 } else {
20451 return -1;
20452 }
20453 }
20454 return 0;
20455 }
20456
20457
20458 #ifdef TCC_TARGET_COFF
20459 #include "tcccoff.c"
20460 #endif
20461
20462 #ifdef TCC_TARGET_PE
20463 #include "tccpe.c"
20464 #endif
20465
20466
20467
20468 static void rt_printline(unsigned long wanted_pc)
20469 {
20470 Stab_Sym *sym, *sym_end;
20471 char func_name[128], last_func_name[128];
20472 unsigned long func_addr, last_pc, pc;
20473 const char *incl_files[INCLUDE_STACK_SIZE];
20474 int incl_index, len, last_line_num, i;
20475 const char *str, *p;
20476
20477 fprintf(stderr, "0x%08lx:", wanted_pc);
20478
20479 func_name[0] = '\0';
20480 func_addr = 0;
20481 incl_index = 0;
20482 last_func_name[0] = '\0';
20483 last_pc = 0xffffffff;
20484 last_line_num = 1;
20485 sym = (Stab_Sym *)stab_section->data + 1;
20486 sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset);
20487 while (sym < sym_end) {
20488 switch(sym->n_type) {
20489
20490 case N_FUN:
20491 if (sym->n_strx == 0) {
20492
20493 = sym->n_value + func_addr;
20494 if (wanted_pc >= last_pc && wanted_pc < pc)
20495 goto found;
20496 func_name[0] = '\0';
20497 func_addr = 0;
20498 } else {
20499 str = stabstr_section->data + sym->n_strx;
20500 p = strchr(str, ':');
20501 if (!p) {
20502 pstrcpy(func_name, sizeof(func_name), str);
20503 } else {
20504 len = p - str;
20505 if (len > sizeof(func_name) - 1)
20506 len = sizeof(func_name) - 1;
20507 memcpy(func_name, str, len);
20508 func_name[len] = '\0';
20509 }
20510 func_addr = sym->n_value;
20511 }
20512 break;
20513
20514 case N_SLINE:
20515 pc = sym->n_value + func_addr;
20516 if (wanted_pc >= last_pc && wanted_pc < pc)
20517 goto found;
20518 last_pc = pc;
20519 last_line_num = sym->n_desc;
20520
20521 (last_func_name, func_name);
20522 break;
20523
20524 case N_BINCL:
20525 str = stabstr_section->data + sym->n_strx;
20526 add_incl:
20527 if (incl_index < INCLUDE_STACK_SIZE) {
20528 incl_files[incl_index++] = str;
20529 }
20530 break;
20531 case N_EINCL:
20532 if (incl_index > 1)
20533 incl_index--;
20534 break;
20535 case N_SO:
20536 if (sym->n_strx == 0) {
20537 incl_index = 0;
20538 } else {
20539 str = stabstr_section->data + sym->n_strx;
20540
20541 = strlen(str);
20542 if (len > 0 && str[len - 1] != '/')
20543 goto add_incl;
20544 }
20545 break;
20546 }
20547 sym++;
20548 }
20549
20550
20551 = 0;
20552 {
20553 Elf32_Sym *sym, *sym_end;
20554 int type;
20555
20556 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
20557 for(sym = (Elf32_Sym *)symtab_section->data + 1;
20558 sym < sym_end;
20559 sym++) {
20560 type = ELF32_ST_TYPE(sym->st_info);
20561 if (type == STT_FUNC) {
20562 if (wanted_pc >= sym->st_value &&
20563 wanted_pc < sym->st_value + sym->st_size) {
20564 pstrcpy(last_func_name, sizeof(last_func_name),
20565 strtab_section->data + sym->st_name);
20566 goto found;
20567 }
20568 }
20569 }
20570 }
20571
20572 (stderr, " ???\n");
20573 return;
20574 found:
20575 if (last_func_name[0] != '\0') {
20576 fprintf(stderr, " %s()", last_func_name);
20577 }
20578 if (incl_index > 0) {
20579 fprintf(stderr, " (%s:%d",
20580 incl_files[incl_index - 1], last_line_num);
20581 for(i = incl_index - 2; i >= 0; i--)
20582 fprintf(stderr, ", included from %s", incl_files[i]);
20583 fprintf(stderr, ")");
20584 }
20585 fprintf(stderr, "\n");
20586 }
20587
20588 #if !defined(WIN32) && !defined(CONFIG_TCCBOOT)
20589
20590
20591 static int rt_get_caller_pc(unsigned long *paddr,
20592 ucontext_t *uc, int level)
20593 {
20594 unsigned long fp __attribute__((unused));
20595
20596
20597 if (level == 0) {
20598 *paddr = 12345;
20599 return 0;
20600 } else {
20601 fp = 23456;
20602 return 0;
20603 }
20604 }
20605
20606
20607 void rt_error(ucontext_t *uc, const char *fmt, ...)
20608 {
20609 va_list ap;
20610 unsigned long pc = 0;
20611 int i;
20612
20613 va_start(ap, fmt);
20614 fprintf(stderr, "Runtime error: ");
20615 vfprintf(stderr, fmt, ap);
20616 fprintf(stderr, "\n");
20617 for(i=0;i<num_callers;i++) {
20618 if (rt_get_caller_pc(&pc, uc, i) < 0)
20619 break;
20620 if (i == 0)
20621 fprintf(stderr, "at ");
20622 else
20623 fprintf(stderr, "by ");
20624 rt_printline(pc);
20625 }
20626 exit(255);
20627 va_end(ap);
20628 }
20629
20630
20631 static void sig_error(int signum, siginfo_t *siginf, void *puc)
20632 {
20633 ucontext_t *uc = puc;
20634
20635 switch(signum) {
20636 case SIGFPE:
20637 switch(siginf->si_code) {
20638 case FPE_INTDIV:
20639 case FPE_FLTDIV:
20640 rt_error(uc, "division by zero");
20641 break;
20642 default:
20643 rt_error(uc, "floating point exception");
20644 break;
20645 }
20646 break;
20647 case SIGBUS:
20648 case SIGSEGV:
20649 if (rt_bound_error_msg && *rt_bound_error_msg)
20650 rt_error(uc, *rt_bound_error_msg);
20651 else
20652 rt_error(uc, "dereferencing invalid pointer");
20653 break;
20654 case SIGILL:
20655 rt_error(uc, "illegal instruction");
20656 break;
20657 case SIGABRT:
20658 rt_error(uc, "abort() called");
20659 break;
20660 default:
20661 rt_error(uc, "caught signal %d", signum);
20662 break;
20663 }
20664 exit(255);
20665 }
20666 #endif
20667
20668
20669 int tcc_relocate(TCCState *s1)
20670 {
20671 Section *s;
20672 int i;
20673
20674 s1->nb_errors = 0;
20675
20676 #ifdef TCC_TARGET_PE
20677 pe_add_runtime(s1);
20678 #else
20679 tcc_add_runtime(s1);
20680 #endif
20681
20682 relocate_common_syms();
20683
20684 tcc_add_linker_symbols(s1);
20685
20686 build_got_entries(s1);
20687
20688
20689
20690 for(i = 1; i < s1->nb_sections; i++) {
20691 s = s1->sections[i];
20692 if (s->sh_flags & SHF_ALLOC) {
20693 if (s->sh_type == SHT_NOBITS)
20694 s->data = tcc_mallocz(s->data_offset);
20695 s->sh_addr = (unsigned long)s->data;
20696 }
20697 }
20698
20699 relocate_syms(s1, 1);
20700
20701 if (s1->nb_errors != 0)
20702 return -1;
20703
20704
20705 for(i = 1; i < s1->nb_sections; i++) {
20706 s = s1->sections[i];
20707 if (s->reloc)
20708 relocate_section(s1, s);
20709 }
20710 return 0;
20711 }
20712
20713
20714 int tcc_run(TCCState *s1, int argc, char **argv)
20715 {
20716 int (*prog_main)(int, char **);
20717
20718 if (tcc_relocate(s1) < 0)
20719 return -1;
20720
20721 prog_main = tcc_get_symbol_err(s1, "main");
20722
20723 if (do_debug) {
20724 #if defined(WIN32) || defined(CONFIG_TCCBOOT)
20725 error("debug mode currently not available for Windows");
20726 #else
20727 struct sigaction sigact;
20728
20729
20730 .sa_flags = SA_SIGINFO | SA_RESETHAND;
20731 sigact.sa_sigaction = sig_error;
20732 sigemptyset(&sigact.sa_mask);
20733 sigaction(SIGFPE, &sigact, NULL);
20734 sigaction(SIGILL, &sigact, NULL);
20735 sigaction(SIGSEGV, &sigact, NULL);
20736 sigaction(SIGBUS, &sigact, NULL);
20737 sigaction(SIGABRT, &sigact, NULL);
20738 #endif
20739 }
20740
20741 #ifdef CONFIG_TCC_BCHECK
20742 if (do_bounds_check) {
20743 void (*bound_init)(void);
20744
20745
20746 = (void *)tcc_get_symbol_err(s1,
20747 "__bound_error_msg");
20748
20749
20750 = (void *)tcc_get_symbol_err(s1, "__bound_init");
20751 bound_init();
20752 }
20753 #endif
20754 return (*prog_main)(argc, argv);
20755 }
20756
20757 TCCState *tcc_new(void)
20758 {
20759 const char *p, *r;
20760 TCCState *s;
20761 TokenSym *ts __attribute__((unused));
20762 int i, c;
20763
20764 s = tcc_mallocz(sizeof(TCCState));
20765 if (!s)
20766 return NULL;
20767 tcc_state = s;
20768 s->output_type = TCC_OUTPUT_MEMORY;
20769
20770
20771 for(i=0;i<256;i++)
20772 isidnum_table[i] = isid(i) || isnum(i);
20773
20774
20775 = NULL;
20776 memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
20777
20778 tok_ident = TOK_IDENT;
20779 p = tcc_keywords;
20780 while (*p) {
20781 r = p;
20782 for(;;) {
20783 c = *r++;
20784 if (c == '\0')
20785 break;
20786 }
20787 ts = tok_alloc(p, r - p - 1);
20788 p = r;
20789 }
20790
20791
20792
20793 (TOK___LINE__, MACRO_OBJ, NULL, NULL);
20794 define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL);
20795 define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
20796 define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
20797
20798
20799 (s, "__STDC__", NULL);
20800 #if defined(TCC_TARGET_I386)
20801 tcc_define_symbol(s, "__i386__", NULL);
20802 #endif
20803 #if defined(TCC_TARGET_ARM)
20804 tcc_define_symbol(s, "__ARM_ARCH_4__", NULL);
20805 tcc_define_symbol(s, "__arm_elf__", NULL);
20806 tcc_define_symbol(s, "__arm_elf", NULL);
20807 tcc_define_symbol(s, "arm_elf", NULL);
20808 tcc_define_symbol(s, "__arm__", NULL);
20809 tcc_define_symbol(s, "__arm", NULL);
20810 tcc_define_symbol(s, "arm", NULL);
20811 tcc_define_symbol(s, "__APCS_32__", NULL);
20812 #endif
20813 #if defined(linux)
20814 tcc_define_symbol(s, "__linux__", NULL);
20815 tcc_define_symbol(s, "linux", NULL);
20816 #endif
20817
20818 (s, "__TINYC__", NULL);
20819
20820
20821 (s, "__SIZE_TYPE__", "unsigned int");
20822 tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int");
20823 tcc_define_symbol(s, "__WCHAR_TYPE__", "int");
20824
20825
20826 #ifdef TCC_TARGET_PE
20827 {
20828 char buf[1024];
20829 snprintf(buf, sizeof(buf), "%s/lib", tcc_lib_path);
20830 tcc_add_library_path(s, buf);
20831 }
20832 #else
20833 tcc_add_library_path(s, "/usr/local/lib");
20834 tcc_add_library_path(s, "/usr/lib");
20835 tcc_add_library_path(s, "/lib");
20836 #endif
20837
20838
20839 ((void ***)&s->sections, &s->nb_sections, NULL);
20840
20841
20842 = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
20843 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
20844 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
20845
20846
20847 = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
20848 ".strtab",
20849 ".hashtab", SHF_PRIVATE);
20850 strtab_section = symtab_section->link;
20851
20852
20853 ->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
20854 ".dynstrtab",
20855 ".dynhashtab", SHF_PRIVATE);
20856 s->alacarte_link = 1;
20857
20858 #ifdef CHAR_IS_UNSIGNED
20859 s->char_is_unsigned = 1;
20860 #endif
20861 #if defined(TCC_TARGET_PE) && 0
20862
20863 ->leading_underscore = 1;
20864 #endif
20865 return s;
20866 }
20867
20868 void tcc_delete(TCCState *s1)
20869 {
20870 int i, n;
20871
20872
20873 (NULL);
20874
20875
20876 = tok_ident - TOK_IDENT;
20877 for(i = 0; i < n; i++)
20878 tcc_free(table_ident[i]);
20879 tcc_free(table_ident);
20880
20881
20882
20883 (symtab_section->hash);
20884
20885 free_section(s1->dynsymtab_section->hash);
20886 free_section(s1->dynsymtab_section->link);
20887 free_section(s1->dynsymtab_section);
20888
20889 for(i = 1; i < s1->nb_sections; i++)
20890 free_section(s1->sections[i]);
20891 tcc_free(s1->sections);
20892
20893
20894 for(i = 0; i < s1->nb_loaded_dlls; i++)
20895 tcc_free(s1->loaded_dlls[i]);
20896 tcc_free(s1->loaded_dlls);
20897
20898
20899 for(i = 0; i < s1->nb_library_paths; i++)
20900 tcc_free(s1->library_paths[i]);
20901 tcc_free(s1->library_paths);
20902
20903
20904 for(i = 0; i < s1->nb_cached_includes; i++)
20905 tcc_free(s1->cached_includes[i]);
20906 tcc_free(s1->cached_includes);
20907
20908 for(i = 0; i < s1->nb_include_paths; i++)
20909 tcc_free(s1->include_paths[i]);
20910 tcc_free(s1->include_paths);
20911
20912 for(i = 0; i < s1->nb_sysinclude_paths; i++)
20913 tcc_free(s1->sysinclude_paths[i]);
20914 tcc_free(s1->sysinclude_paths);
20915
20916 tcc_free(s1);
20917 }
20918
20919 int tcc_add_include_path(TCCState *s1, const char *pathname)
20920 {
20921 char *pathname1;
20922
20923 pathname1 = tcc_strdup(pathname);
20924 dynarray_add((void ***)&s1->include_paths, &s1->nb_include_paths, pathname1);
20925 return 0;
20926 }
20927
20928 int tcc_add_sysinclude_path(TCCState *s1, const char *pathname)
20929 {
20930 char *pathname1;
20931
20932 pathname1 = tcc_strdup(pathname);
20933 dynarray_add((void ***)&s1->sysinclude_paths, &s1->nb_sysinclude_paths, pathname1);
20934 return 0;
20935 }
20936
20937 static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
20938 {
20939 const char *ext, *filename1;
20940 Elf32_Ehdr ehdr;
20941 int fd, ret;
20942 BufferedFile *saved_file;
20943
20944
20945 = strrchr(filename, '/');
20946 if (filename1)
20947 filename1++;
20948 else
20949 filename1 = filename;
20950 ext = strrchr(filename1, '.');
20951 if (ext)
20952 ext++;
20953
20954
20955 = file;
20956 file = tcc_open(s1, filename);
20957 if (!file) {
20958 if (flags & AFF_PRINT_ERROR) {
20959 error_noabort("file '%s' not found", filename);
20960 }
20961 ret = -1;
20962 goto fail1;
20963 }
20964
20965 if (!ext || !strcmp(ext, "c")) {
20966
20967 = tcc_compile(s1);
20968 } else
20969 #ifdef CONFIG_TCC_ASM
20970 if (!strcmp(ext, "S")) {
20971
20972 = tcc_assemble(s1, 1);
20973 } else if (!strcmp(ext, "s")) {
20974
20975 = tcc_assemble(s1, 0);
20976 } else
20977 #endif
20978 #ifdef TCC_TARGET_PE
20979 if (!strcmp(ext, "def")) {
20980 ret = pe_load_def_file(s1, fdopen(file->fd, "rb"));
20981 } else
20982 #endif
20983 {
20984 fd = file->fd;
20985
20986 = read(fd, &ehdr, sizeof(ehdr));
20987 lseek(fd, 0, SEEK_SET);
20988 if (ret <= 0) {
20989 error_noabort("could not read header");
20990 goto fail;
20991 } else if (ret != sizeof(ehdr)) {
20992 goto try_load_script;
20993 }
20994
20995 if (ehdr.e_ident[0] == ELFMAG0 &&
20996 ehdr.e_ident[1] == ELFMAG1 &&
20997 ehdr.e_ident[2] == ELFMAG2 &&
20998 ehdr.e_ident[3] == ELFMAG3) {
20999 file->line_num = 0;
21000 if (ehdr.e_type == ET_REL) {
21001 ret = tcc_load_object_file(s1, fd, 0);
21002 } else if (ehdr.e_type == ET_DYN) {
21003 if (s1->output_type == TCC_OUTPUT_MEMORY) {
21004 #ifdef TCC_TARGET_PE
21005 ret = -1;
21006 #else
21007 void *h;
21008 assert(0);
21009 h = 0;
21010
21011
21012 if (h)
21013 ret = 0;
21014 else
21015 ret = -1;
21016 #endif
21017 } else {
21018 ret = tcc_load_dll(s1, fd, filename,
21019 (flags & AFF_REFERENCED_DLL) != 0);
21020 }
21021 } else {
21022 error_noabort("unrecognized ELF file");
21023 goto fail;
21024 }
21025 } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
21026 file->line_num = 0;
21027 = tcc_load_archive(s1, fd);
21028 } else
21029 #ifdef TCC_TARGET_COFF
21030 if (*(uint16_t *)(&ehdr) == COFF_C67_MAGIC) {
21031 ret = tcc_load_coff(s1, fd);
21032 } else
21033 #endif
21034 {
21035
21036 try_load_script:
21037 ret = tcc_load_ldscript(s1);
21038 if (ret < 0) {
21039 error_noabort("unrecognized file type");
21040 goto fail;
21041 }
21042 }
21043 }
21044 the_end:
21045 tcc_close(file);
21046 fail1:
21047 file = saved_file;
21048 return ret;
21049 fail:
21050 ret = -1;
21051 goto the_end;
21052 }
21053
21054 int tcc_add_file(TCCState *s, const char *filename)
21055 {
21056 return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
21057 }
21058
21059 int tcc_add_library_path(TCCState *s, const char *pathname)
21060 {
21061 char *pathname1;
21062
21063 pathname1 = tcc_strdup(pathname);
21064 dynarray_add((void ***)&s->library_paths, &s->nb_library_paths, pathname1);
21065 return 0;
21066 }
21067
21068
21069
21070 static int tcc_add_dll(TCCState *s, const char *filename, int flags)
21071 {
21072 char buf[1024];
21073 int i;
21074
21075 for(i = 0; i < s->nb_library_paths; i++) {
21076 snprintf(buf, sizeof(buf), "%s/%s",
21077 s->library_paths[i], filename);
21078 if (tcc_add_file_internal(s, buf, flags) == 0)
21079 return 0;
21080 }
21081 return -1;
21082 }
21083
21084
21085 int tcc_add_library(TCCState *s, const char *libraryname)
21086 {
21087 char buf[1024];
21088 int i;
21089
21090
21091 if (!s->static_link) {
21092 #ifdef TCC_TARGET_PE
21093 snprintf(buf, sizeof(buf), "%s.def", libraryname);
21094 #else
21095 snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
21096 #endif
21097 if (tcc_add_dll(s, buf, 0) == 0)
21098 return 0;
21099 }
21100
21101
21102 for(i = 0; i < s->nb_library_paths; i++) {
21103 snprintf(buf, sizeof(buf), "%s/lib%s.a",
21104 s->library_paths[i], libraryname);
21105 if (tcc_add_file_internal(s, buf, 0) == 0)
21106 return 0;
21107 }
21108 return -1;
21109 }
21110
21111 int tcc_add_symbol(TCCState *s, const char *name, unsigned long val)
21112 {
21113 add_elf_sym(symtab_section, val, 0,
21114 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
21115 SHN_ABS, name);
21116 return 0;
21117 }
21118
21119 int tcc_set_output_type(TCCState *s, int output_type)
21120 {
21121 s->output_type = output_type;
21122
21123 if (!s->nostdinc) {
21124 char buf[1024];
21125
21126
21127
21128 #ifndef TCC_TARGET_PE
21129 tcc_add_sysinclude_path(s, "/usr/local/include");
21130 tcc_add_sysinclude_path(s, "/usr/include");
21131 #endif
21132 snprintf(buf, sizeof(buf), "%s/include", tcc_lib_path);
21133 tcc_add_sysinclude_path(s, buf);
21134 #ifdef TCC_TARGET_PE
21135 snprintf(buf, sizeof(buf), "%s/include/winapi", tcc_lib_path);
21136 tcc_add_sysinclude_path(s, buf);
21137 #endif
21138 }
21139
21140
21141 #ifdef CONFIG_TCC_BCHECK
21142 if (do_bounds_check) {
21143
21144 (s, "__BOUNDS_CHECKING_ON", NULL);
21145
21146 = new_section(s, ".bounds",
21147 SHT_PROGBITS, SHF_ALLOC);
21148 lbounds_section = new_section(s, ".lbounds",
21149 SHT_PROGBITS, SHF_ALLOC);
21150 }
21151 #endif
21152
21153 if (s->char_is_unsigned) {
21154 tcc_define_symbol(s, "__CHAR_UNSIGNED__", NULL);
21155 }
21156
21157
21158 if (do_debug) {
21159
21160 = new_section(s, ".stab", SHT_PROGBITS, 0);
21161 stab_section->sh_entsize = sizeof(Stab_Sym);
21162 stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
21163 put_elf_str(stabstr_section, "");
21164 stab_section->link = stabstr_section;
21165
21166 ("", 0, 0, 0, 0);
21167 }
21168
21169
21170 #ifndef TCC_TARGET_PE
21171 if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) &&
21172 !s->nostdlib) {
21173 if (output_type != TCC_OUTPUT_DLL)
21174 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
21175 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
21176 }
21177 #endif
21178 return 0;
21179 }
21180
21181 #define WD_ALL 0x0001
21182 #define FD_INVERT 0x0002
21183
21184 typedef struct FlagDef {
21185 uint16_t offset;
21186 uint16_t flags;
21187 const char *name;
21188 } FlagDef;
21189
21190 static const FlagDef warning_defs[] = {
21191 { offsetof(TCCState, warn_unsupported), 0, "unsupported" },
21192 { offsetof(TCCState, warn_write_strings), 0, "write-strings" },
21193 { offsetof(TCCState, warn_error), 0, "error" },
21194 { offsetof(TCCState, warn_implicit_function_declaration), WD_ALL,
21195 "implicit-function-declaration" },
21196 };
21197
21198 static int set_flag(TCCState *s, const FlagDef *flags, int nb_flags,
21199 const char *name, int value)
21200 {
21201 int i;
21202 const FlagDef *p;
21203 const char *r;
21204
21205 r = name;
21206 if (r[0] == 'n' && r[1] == 'o' && r[2] == '-') {
21207 r += 3;
21208 value = !value;
21209 }
21210 for(i = 0, p = flags; i < nb_flags; i++, p++) {
21211 if (!strcmp(r, p->name))
21212 goto found;
21213 }
21214 return -1;
21215 found:
21216 if (p->flags & FD_INVERT)
21217 value = !value;
21218 *(int *)((uint8_t *)s + p->offset) = value;
21219 return 0;
21220 }
21221
21222
21223
21224 int tcc_set_warning(TCCState *s, const char *warning_name, int value)
21225 {
21226 int i;
21227 const FlagDef *p;
21228
21229 if (!strcmp(warning_name, "all")) {
21230 for(i = 0, p = warning_defs; i < countof(warning_defs); i++, p++) {
21231 if (p->flags & WD_ALL)
21232 *(int *)((uint8_t *)s + p->offset) = 1;
21233 }
21234 return 0;
21235 } else {
21236 return set_flag(s, warning_defs, countof(warning_defs),
21237 warning_name, value);
21238 }
21239 }
21240
21241 static const FlagDef flag_defs[] = {
21242 { offsetof(TCCState, char_is_unsigned), 0, "unsigned-char" },
21243 { offsetof(TCCState, char_is_unsigned), FD_INVERT, "signed-char" },
21244 { offsetof(TCCState, nocommon), FD_INVERT, "common" },
21245 { offsetof(TCCState, leading_underscore), 0, "leading-underscore" },
21246 };
21247
21248
21249 int tcc_set_flag(TCCState *s, const char *flag_name, int value)
21250 {
21251 return set_flag(s, flag_defs, countof(flag_defs),
21252 flag_name, value);
21253 }
21254
21255 #if !defined(LIBTCC)
21256
21257
21258 static const char *tcc_basename(const char *name)
21259 {
21260 const char *p;
21261 p = strrchr(name, '/');
21262 #ifdef WIN32
21263 if (!p)
21264 p = strrchr(name, '\\');
21265 #endif
21266 if (!p)
21267 p = name;
21268 else
21269 p++;
21270 return p;
21271 }
21272
21273 static int64_t getclock_us(void)
21274 {
21275 #ifdef WIN32
21276 struct _timeb tb;
21277 _ftime(&tb);
21278 return (tb.time * 1000LL + tb.millitm) * 1000LL;
21279 #else
21280 struct timeval tv;
21281 gettimeofday(&tv, NULL);
21282 return tv.tv_sec * 1000000LL + tv.tv_usec;
21283 #endif
21284 }
21285
21286 void help(void)
21287 {
21288 printf("tcc version " TCC_VERSION " - Tiny C Compiler - Copyright (C) 2001-2010 Fabrice Bellard\n"
21289 "usage: tcc [-v] [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
21290 " [-Wwarn] [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
21291 " [infile1 infile2...] [-run infile args...]\n"
21292 "\n"
21293 "General options:\n"
21294 " -v display current version\n"
21295 " -c compile only - generate an object file\n"
21296 " -o outfile set output filename\n"
21297 " -Bdir set tcc internal library path\n"
21298 " -bench output compilation statistics\n"
21299 " -run run compiled source\n"
21300 " -fflag set or reset (with 'no-' prefix) 'flag' (see man page)\n"
21301 " -Wwarning set or reset (with 'no-' prefix) 'warning' (see man page)\n"
21302 " -w disable all warnings\n"
21303 "Preprocessor options:\n"
21304 " -Idir add include path 'dir'\n"
21305 " -Dsym[=val] define 'sym' with value 'val'\n"
21306 " -Usym undefine 'sym'\n"
21307 "Linker options:\n"
21308 " -Ldir add library path 'dir'\n"
21309 " -llib link with dynamic or static library 'lib'\n"
21310 " -shared generate a shared library\n"
21311 " -static static linking\n"
21312 " -rdynamic export all global symbols to dynamic linker\n"
21313 " -r relocatable output\n"
21314 "Debugger options:\n"
21315 " -g generate runtime debug info\n"
21316 #ifdef CONFIG_TCC_BCHECK
21317 " -b compile with built-in memory and bounds checker (implies -g)\n"
21318 #endif
21319 " -bt N show N callers in stack traces\n"
21320 );
21321 }
21322
21323 #define TCC_OPTION_HAS_ARG 0x0001
21324 #define TCC_OPTION_NOSEP 0x0002
21325
21326 typedef struct TCCOption {
21327 const char *name;
21328 uint16_t index;
21329 uint16_t flags;
21330 } TCCOption;
21331
21332 enum {
21333 TCC_OPTION_HELP,
21334 TCC_OPTION_I,
21335 TCC_OPTION_D,
21336 TCC_OPTION_U,
21337 TCC_OPTION_L,
21338 TCC_OPTION_B,
21339 TCC_OPTION_l,
21340 TCC_OPTION_bench,
21341 TCC_OPTION_bt,
21342 TCC_OPTION_b,
21343 TCC_OPTION_g,
21344 TCC_OPTION_c,
21345 TCC_OPTION_static,
21346 TCC_OPTION_shared,
21347 TCC_OPTION_o,
21348 TCC_OPTION_r,
21349 TCC_OPTION_Wl,
21350 TCC_OPTION_W,
21351 TCC_OPTION_O,
21352 TCC_OPTION_m,
21353 TCC_OPTION_f,
21354 TCC_OPTION_nostdinc,
21355 TCC_OPTION_nostdlib,
21356 TCC_OPTION_print_search_dirs,
21357 TCC_OPTION_rdynamic,
21358 TCC_OPTION_run,
21359 TCC_OPTION_v,
21360 TCC_OPTION_w,
21361 TCC_OPTION_pipe,
21362 };
21363
21364 static const TCCOption tcc_options[] = {
21365 { "h", TCC_OPTION_HELP, 0 },
21366 { "?", TCC_OPTION_HELP, 0 },
21367 { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG },
21368 { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG },
21369 { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG },
21370 { "L", TCC_OPTION_L, TCC_OPTION_HAS_ARG },
21371 { "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG },
21372 { "l", TCC_OPTION_l, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
21373 { "bench", TCC_OPTION_bench, 0 },
21374 { "bt", TCC_OPTION_bt, TCC_OPTION_HAS_ARG },
21375 #ifdef CONFIG_TCC_BCHECK
21376 { "b", TCC_OPTION_b, 0 },
21377 #endif
21378 { "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
21379 { "c", TCC_OPTION_c, 0 },
21380 { "static", TCC_OPTION_static, 0 },
21381 { "shared", TCC_OPTION_shared, 0 },
21382 { "o", TCC_OPTION_o, TCC_OPTION_HAS_ARG },
21383 { "run", TCC_OPTION_run, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
21384 { "rdynamic", TCC_OPTION_rdynamic, 0 },
21385 { "r", TCC_OPTION_r, 0 },
21386 { "Wl,", TCC_OPTION_Wl, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
21387 { "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
21388 { "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
21389 { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG },
21390 { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
21391 { "nostdinc", TCC_OPTION_nostdinc, 0 },
21392 { "nostdlib", TCC_OPTION_nostdlib, 0 },
21393 { "print-search-dirs", TCC_OPTION_print_search_dirs, 0 },
21394 { "v", TCC_OPTION_v, 0 },
21395 { "w", TCC_OPTION_w, 0 },
21396 { "pipe", TCC_OPTION_pipe, 0},
21397 { NULL },
21398 };
21399
21400
21401 static int expand_args(char ***pargv, const char *str)
21402 {
21403 const char *s1;
21404 char **argv, *arg;
21405 int argc, len;
21406
21407 argc = 0;
21408 argv = NULL;
21409 for(;;) {
21410 while (is_space(*str))
21411 str++;
21412 if (*str == '\0')
21413 break;
21414 s1 = str;
21415 while (*str != '\0' && !is_space(*str))
21416 str++;
21417 len = str - s1;
21418 arg = tcc_malloc(len + 1);
21419 memcpy(arg, s1, len);
21420 arg[len] = '\0';
21421 dynarray_add((void ***)&argv, &argc, arg);
21422 }
21423 *pargv = argv;
21424 return argc;
21425 }
21426
21427 static char **files;
21428 static int nb_files, nb_libraries;
21429 static int multiple_files;
21430 static int print_search_dirs;
21431 static int output_type;
21432 static int reloc_output;
21433 static const char *outfile;
21434
21435 int parse_args(TCCState *s, int argc, char **argv)
21436 {
21437 int optind;
21438 const TCCOption *popt;
21439 const char *optarg, *p1, *r1;
21440 char *r;
21441
21442 optind = 0;
21443 while (1) {
21444 if (optind >= argc) {
21445 if (nb_files == 0 && !print_search_dirs)
21446 goto show_help;
21447 else
21448 break;
21449 }
21450 r = argv[optind++];
21451 if (r[0] != '-') {
21452
21453 ((void ***)&files, &nb_files, r);
21454 if (!multiple_files) {
21455 optind--;
21456
21457 break;
21458 }
21459 } else {
21460
21461 = tcc_options;
21462 for(;;) {
21463 p1 = popt->name;
21464 if (p1 == NULL)
21465 error("invalid option -- '%s'", r);
21466 r1 = r + 1;
21467 for(;;) {
21468 if (*p1 == '\0')
21469 goto option_found;
21470 if (*r1 != *p1)
21471 break;
21472 p1++;
21473 r1++;
21474 }
21475 popt++;
21476 }
21477 option_found:
21478 if (popt->flags & TCC_OPTION_HAS_ARG) {
21479 if (*r1 != '\0' || (popt->flags & TCC_OPTION_NOSEP)) {
21480 optarg = r1;
21481 } else {
21482 if (optind >= argc)
21483 error("argument to '%s' is missing", r);
21484 optarg = argv[optind++];
21485 }
21486 } else {
21487 if (*r1 != '\0')
21488 goto show_help;
21489 optarg = NULL;
21490 }
21491
21492 switch(popt->index) {
21493 case TCC_OPTION_HELP:
21494 show_help:
21495 help();
21496 exit(1);
21497 case TCC_OPTION_I:
21498 if (tcc_add_include_path(s, optarg) < 0)
21499 error("too many include paths");
21500 break;
21501 case TCC_OPTION_D:
21502 {
21503 char *sym, *value;
21504 sym = (char *)optarg;
21505 value = strchr(sym, '=');
21506 if (value) {
21507 *value = '\0';
21508 value++;
21509 }
21510 tcc_define_symbol(s, sym, value);
21511 }
21512 break;
21513 case TCC_OPTION_U:
21514 tcc_undefine_symbol(s, optarg);
21515 break;
21516 case TCC_OPTION_L:
21517 tcc_add_library_path(s, optarg);
21518 break;
21519 case TCC_OPTION_B:
21520
21521 = optarg;
21522 break;
21523 case TCC_OPTION_l:
21524 dynarray_add((void ***)&files, &nb_files, r);
21525 nb_libraries++;
21526 break;
21527 case TCC_OPTION_bench:
21528 do_bench = 1;
21529 break;
21530 case TCC_OPTION_bt:
21531 num_callers = atoi(optarg);
21532 break;
21533 #ifdef CONFIG_TCC_BCHECK
21534 case TCC_OPTION_b:
21535 do_bounds_check = 1;
21536 do_debug = 1;
21537 break;
21538 #endif
21539 case TCC_OPTION_g:
21540 do_debug = 1;
21541 break;
21542 case TCC_OPTION_c:
21543 multiple_files = 1;
21544 output_type = TCC_OUTPUT_OBJ;
21545 break;
21546 case TCC_OPTION_static:
21547 s->static_link = 1;
21548 break;
21549 case TCC_OPTION_shared:
21550 output_type = TCC_OUTPUT_DLL;
21551 break;
21552 case TCC_OPTION_o:
21553 multiple_files = 1;
21554 outfile = optarg;
21555 break;
21556 case TCC_OPTION_r:
21557
21558 = 1;
21559 output_type = TCC_OUTPUT_OBJ;
21560 break;
21561 case TCC_OPTION_nostdinc:
21562 s->nostdinc = 1;
21563 break;
21564 case TCC_OPTION_nostdlib:
21565 s->nostdlib = 1;
21566 break;
21567 case TCC_OPTION_print_search_dirs:
21568 print_search_dirs = 1;
21569 break;
21570 case TCC_OPTION_run:
21571 {
21572 int argc1;
21573 char **argv1;
21574 argc1 = expand_args(&argv1, optarg);
21575 if (argc1 > 0) {
21576 parse_args(s, argc1, argv1);
21577 }
21578 multiple_files = 0;
21579 output_type = TCC_OUTPUT_MEMORY;
21580 }
21581 break;
21582 case TCC_OPTION_v:
21583 printf("tcc version %s\n", TCC_VERSION);
21584 exit(0);
21585 case TCC_OPTION_f:
21586 if (tcc_set_flag(s, optarg, 1) < 0 && s->warn_unsupported)
21587 goto unsupported_option;
21588 break;
21589 case TCC_OPTION_W:
21590 if (tcc_set_warning(s, optarg, 1) < 0 &&
21591 s->warn_unsupported)
21592 goto unsupported_option;
21593 break;
21594 case TCC_OPTION_w:
21595 s->warn_none = 1;
21596 break;
21597 case TCC_OPTION_rdynamic:
21598 s->rdynamic = 1;
21599 break;
21600 case TCC_OPTION_Wl:
21601 {
21602 const char *p;
21603 if (strstart(optarg, "-Ttext,", &p)) {
21604 s->text_addr = strtoul(p, NULL, 16);
21605 s->has_text_addr = 1;
21606 } else if (strstart(optarg, "--oformat,", &p)) {
21607 if (strstart(p, "elf32-", NULL)) {
21608 s->output_format = TCC_OUTPUT_FORMAT_ELF;
21609 } else if (!strcmp(p, "binary")) {
21610 s->output_format = TCC_OUTPUT_FORMAT_BINARY;
21611 } else
21612 #ifdef TCC_TARGET_COFF
21613 if (!strcmp(p, "coff")) {
21614 s->output_format = TCC_OUTPUT_FORMAT_COFF;
21615 } else
21616 #endif
21617 {
21618 error("target %s not found", p);
21619 }
21620 } else {
21621 error("unsupported linker option '%s'", optarg);
21622 }
21623 }
21624 break;
21625 default:
21626 if (s->warn_unsupported) {
21627 unsupported_option:
21628 warning("unsupported option '%s'", r);
21629 }
21630 break;
21631 }
21632 }
21633 }
21634 return optind;
21635 }
21636
21637
21638 int main2(int argc, char **argv)
21639 {
21640 int i;
21641 TCCState *s;
21642 int nb_objfiles, ret, optind;
21643 char objfilename[1024];
21644 int64_t start_time = 0;
21645
21646 #ifdef WIN32
21647
21648
21649 {
21650 static char path[1024];
21651 char *p, *d;
21652
21653 GetModuleFileNameA(NULL, path, sizeof path);
21654 p = d = strlwr(path);
21655 while (*d)
21656 {
21657 if (*d == '\\') *d = '/', p = d;
21658 ++d;
21659 }
21660 *p = '\0';
21661 tcc_lib_path = path;
21662 }
21663 #endif
21664
21665 s = tcc_new();
21666 output_type = TCC_OUTPUT_EXE;
21667 outfile = NULL;
21668 multiple_files = 1;
21669 files = NULL;
21670 nb_files = 0;
21671 nb_libraries = 0;
21672 reloc_output = 0;
21673 print_search_dirs = 0;
21674
21675 optind = parse_args(s, argc - 1, argv + 1) + 1;
21676
21677 if (print_search_dirs) {
21678
21679 ("install: %s/\n", tcc_lib_path);
21680 return 0;
21681 }
21682
21683 nb_objfiles = nb_files - nb_libraries;
21684
21685
21686
21687 if (outfile && output_type == TCC_OUTPUT_MEMORY)
21688 output_type = TCC_OUTPUT_EXE;
21689
21690
21691 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
21692
21693 if (nb_objfiles != 1)
21694 error("cannot specify multiple files with -c");
21695 if (nb_libraries != 0)
21696 error("cannot specify libraries with -c");
21697 }
21698
21699 if (output_type != TCC_OUTPUT_MEMORY) {
21700 if (!outfile) {
21701
21702 (objfilename, sizeof(objfilename) - 1,
21703
21704 (files[0]));
21705 #ifdef TCC_TARGET_PE
21706 pe_guess_outfile(objfilename, output_type);
21707 #else
21708 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
21709 char *ext = strrchr(objfilename, '.');
21710 if (!ext)
21711 goto default_outfile;
21712
21713 (ext + 1, "o");
21714 } else {
21715 default_outfile:
21716 pstrcpy(objfilename, sizeof(objfilename), "a.out");
21717 }
21718 #endif
21719 outfile = objfilename;
21720 }
21721 }
21722
21723 if (do_bench) {
21724 start_time = getclock_us();
21725 }
21726
21727 tcc_set_output_type(s, output_type);
21728
21729
21730 for(i = 0;i < nb_files; i++) {
21731 const char *filename;
21732
21733 filename = files[i];
21734 if (filename[0] == '-') {
21735 if (tcc_add_library(s, filename + 2) < 0)
21736 error("cannot find %s", filename);
21737 } else {
21738 if (tcc_add_file(s, filename) < 0) {
21739 ret = 1;
21740 goto the_end;
21741 }
21742 }
21743 }
21744
21745
21746 (files);
21747
21748 if (do_bench) {
21749 double total_time;
21750 total_time = (double)(getclock_us() - start_time) / 1000000.0;
21751 if (total_time < 0.001)
21752 total_time = 0.001;
21753 if (total_bytes < 1)
21754 total_bytes = 1;
21755 printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
21756 tok_ident - TOK_IDENT, total_lines, total_bytes,
21757 total_time, (int)(total_lines / total_time),
21758 total_bytes / total_time / 1000000.0);
21759 }
21760
21761 if (s->output_type == TCC_OUTPUT_MEMORY) {
21762 ret = tcc_run(s, argc - optind, argv + optind);
21763 } else
21764 #ifdef TCC_TARGET_PE
21765 if (s->output_type != TCC_OUTPUT_OBJ) {
21766 ret = tcc_output_pe(s, outfile);
21767 } else
21768 #endif
21769 {
21770 tcc_output_file(s, outfile);
21771 ret = 0;
21772 }
21773 the_end:
21774
21775 if (!do_bounds_check)
21776 tcc_delete(s);
21777
21778 #ifdef MEM_DEBUG
21779 if (do_bench) {
21780 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size);
21781 }
21782 #endif
21783 return ret;
21784 }
21785
21786
21787
21788
21789
21790
21791 int main(int argc, char **argv)
21792 {
21793 #define REPS 30
21794 int i;
21795 for (i = 0; i < REPS; i++) {
21796 main2(argc, argv);
21797 }
21798 return 0;
21799 }
21800
21801 #endif
21802
21803
21804
21805 unsigned short __tcc_fpu_control = 0x137f;
21806 unsigned short __tcc_int_fpu_control = 0x137f | 0x0c00;
21807
21808 #if 0
21809 long long __shldi3(long long a, int b)
21810 {
21811 #ifdef __TINYC__
21812 DWunion u;
21813 u.ll = a;
21814 if (b >= 32) {
21815 u.s.high = (unsigned)u.s.low << (b - 32);
21816 u.s.low = 0;
21817 } else if (b != 0) {
21818 u.s.high = ((unsigned)u.s.high << b) | (u.s.low >> (32 - b));
21819 u.s.low = (unsigned)u.s.low << b;
21820 }
21821 return u.ll;
21822 #else
21823 return a << b;
21824 #endif
21825 }
21826 #endif
21827